diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/Space.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/i825xx/3c505.c | 1672 | ||||
-rw-r--r-- | drivers/net/ethernet/i825xx/3c505.h | 292 | ||||
-rw-r--r-- | drivers/net/ethernet/i825xx/3c507.c | 939 | ||||
-rw-r--r-- | drivers/net/ethernet/i825xx/Kconfig | 23 | ||||
-rw-r--r-- | drivers/net/ethernet/i825xx/Makefile | 2 |
6 files changed, 0 insertions, 2936 deletions
diff --git a/drivers/net/Space.c b/drivers/net/Space.c index d48712751357..ac66a6af7138 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c | |||
@@ -51,8 +51,6 @@ extern struct net_device *fmv18x_probe(int unit); | |||
51 | extern struct net_device *eth16i_probe(int unit); | 51 | extern struct net_device *eth16i_probe(int unit); |
52 | extern struct net_device *i82596_probe(int unit); | 52 | extern struct net_device *i82596_probe(int unit); |
53 | extern struct net_device *ewrk3_probe(int unit); | 53 | extern struct net_device *ewrk3_probe(int unit); |
54 | extern struct net_device *el16_probe(int unit); | ||
55 | extern struct net_device *elplus_probe(int unit); | ||
56 | extern struct net_device *e2100_probe(int unit); | 54 | extern struct net_device *e2100_probe(int unit); |
57 | extern struct net_device *ni5010_probe(int unit); | 55 | extern struct net_device *ni5010_probe(int unit); |
58 | extern struct net_device *ni52_probe(int unit); | 56 | extern struct net_device *ni52_probe(int unit); |
@@ -164,12 +162,6 @@ static struct devprobe2 isa_probes[] __initdata = { | |||
164 | #if defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) /* Intel I82596 */ | 162 | #if defined(CONFIG_MVME16x_NET) || defined(CONFIG_BVME6000_NET) /* Intel I82596 */ |
165 | {i82596_probe, 0}, | 163 | {i82596_probe, 0}, |
166 | #endif | 164 | #endif |
167 | #ifdef CONFIG_EL16 /* 3c507 */ | ||
168 | {el16_probe, 0}, | ||
169 | #endif | ||
170 | #ifdef CONFIG_ELPLUS /* 3c505 */ | ||
171 | {elplus_probe, 0}, | ||
172 | #endif | ||
173 | #ifdef CONFIG_NI5010 | 165 | #ifdef CONFIG_NI5010 |
174 | {ni5010_probe, 0}, | 166 | {ni5010_probe, 0}, |
175 | #endif | 167 | #endif |
diff --git a/drivers/net/ethernet/i825xx/3c505.c b/drivers/net/ethernet/i825xx/3c505.c deleted file mode 100644 index 6d000d678a58..000000000000 --- a/drivers/net/ethernet/i825xx/3c505.c +++ /dev/null | |||
@@ -1,1672 +0,0 @@ | |||
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/ioport.h> | ||
106 | #include <linux/spinlock.h> | ||
107 | #include <linux/ethtool.h> | ||
108 | #include <linux/delay.h> | ||
109 | #include <linux/bitops.h> | ||
110 | #include <linux/gfp.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 | #define timeout_msg "*** timeout at %s:%s (line %d) ***\n" | ||
130 | #define TIMEOUT_MSG(lineno) \ | ||
131 | pr_notice(timeout_msg, __FILE__, __func__, (lineno)) | ||
132 | |||
133 | #define invalid_pcb_msg "*** invalid pcb length %d at %s:%s (line %d) ***\n" | ||
134 | #define INVALID_PCB_MSG(len) \ | ||
135 | pr_notice(invalid_pcb_msg, (len), __FILE__, __func__, __LINE__) | ||
136 | |||
137 | #define search_msg "%s: Looking for 3c505 adapter at address %#x..." | ||
138 | |||
139 | #define stilllooking_msg "still looking..." | ||
140 | |||
141 | #define found_msg "found.\n" | ||
142 | |||
143 | #define notfound_msg "not found (reason = %d)\n" | ||
144 | |||
145 | #define couldnot_msg "%s: 3c505 not found\n" | ||
146 | |||
147 | /********************************************************* | ||
148 | * | ||
149 | * various other debug stuff | ||
150 | * | ||
151 | *********************************************************/ | ||
152 | |||
153 | #ifdef ELP_DEBUG | ||
154 | static int elp_debug = ELP_DEBUG; | ||
155 | #else | ||
156 | static int elp_debug; | ||
157 | #endif | ||
158 | #define debug elp_debug | ||
159 | |||
160 | /* | ||
161 | * 0 = no messages (well, some) | ||
162 | * 1 = messages when high level commands performed | ||
163 | * 2 = messages when low level commands performed | ||
164 | * 3 = messages when interrupts received | ||
165 | */ | ||
166 | |||
167 | /***************************************************************** | ||
168 | * | ||
169 | * List of I/O-addresses we try to auto-sense | ||
170 | * Last element MUST BE 0! | ||
171 | *****************************************************************/ | ||
172 | |||
173 | static int addr_list[] __initdata = {0x300, 0x280, 0x310, 0}; | ||
174 | |||
175 | /* Dma Memory related stuff */ | ||
176 | |||
177 | static unsigned long dma_mem_alloc(int size) | ||
178 | { | ||
179 | int order = get_order(size); | ||
180 | return __get_dma_pages(GFP_KERNEL, order); | ||
181 | } | ||
182 | |||
183 | |||
184 | /***************************************************************** | ||
185 | * | ||
186 | * Functions for I/O (note the inline !) | ||
187 | * | ||
188 | *****************************************************************/ | ||
189 | |||
190 | static inline unsigned char inb_status(unsigned int base_addr) | ||
191 | { | ||
192 | return inb(base_addr + PORT_STATUS); | ||
193 | } | ||
194 | |||
195 | static inline int inb_command(unsigned int base_addr) | ||
196 | { | ||
197 | return inb(base_addr + PORT_COMMAND); | ||
198 | } | ||
199 | |||
200 | static inline void outb_control(unsigned char val, struct net_device *dev) | ||
201 | { | ||
202 | outb(val, dev->base_addr + PORT_CONTROL); | ||
203 | ((elp_device *)(netdev_priv(dev)))->hcr_val = val; | ||
204 | } | ||
205 | |||
206 | #define HCR_VAL(x) (((elp_device *)(netdev_priv(x)))->hcr_val) | ||
207 | |||
208 | static inline void outb_command(unsigned char val, unsigned int base_addr) | ||
209 | { | ||
210 | outb(val, base_addr + PORT_COMMAND); | ||
211 | } | ||
212 | |||
213 | static inline unsigned int backlog_next(unsigned int n) | ||
214 | { | ||
215 | return (n + 1) % BACKLOG_SIZE; | ||
216 | } | ||
217 | |||
218 | /***************************************************************** | ||
219 | * | ||
220 | * useful functions for accessing the adapter | ||
221 | * | ||
222 | *****************************************************************/ | ||
223 | |||
224 | /* | ||
225 | * use this routine when accessing the ASF bits as they are | ||
226 | * changed asynchronously by the adapter | ||
227 | */ | ||
228 | |||
229 | /* get adapter PCB status */ | ||
230 | #define GET_ASF(addr) \ | ||
231 | (get_status(addr)&ASF_PCB_MASK) | ||
232 | |||
233 | static inline int get_status(unsigned int base_addr) | ||
234 | { | ||
235 | unsigned long timeout = jiffies + 10*HZ/100; | ||
236 | register int stat1; | ||
237 | do { | ||
238 | stat1 = inb_status(base_addr); | ||
239 | } while (stat1 != inb_status(base_addr) && time_before(jiffies, timeout)); | ||
240 | if (time_after_eq(jiffies, timeout)) | ||
241 | TIMEOUT_MSG(__LINE__); | ||
242 | return stat1; | ||
243 | } | ||
244 | |||
245 | static inline void set_hsf(struct net_device *dev, int hsf) | ||
246 | { | ||
247 | elp_device *adapter = netdev_priv(dev); | ||
248 | unsigned long flags; | ||
249 | |||
250 | spin_lock_irqsave(&adapter->lock, flags); | ||
251 | outb_control((HCR_VAL(dev) & ~HSF_PCB_MASK) | hsf, dev); | ||
252 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
253 | } | ||
254 | |||
255 | static bool start_receive(struct net_device *, pcb_struct *); | ||
256 | |||
257 | static inline void adapter_reset(struct net_device *dev) | ||
258 | { | ||
259 | unsigned long timeout; | ||
260 | elp_device *adapter = netdev_priv(dev); | ||
261 | unsigned char orig_hcr = adapter->hcr_val; | ||
262 | |||
263 | outb_control(0, dev); | ||
264 | |||
265 | if (inb_status(dev->base_addr) & ACRF) { | ||
266 | do { | ||
267 | inb_command(dev->base_addr); | ||
268 | timeout = jiffies + 2*HZ/100; | ||
269 | while (time_before_eq(jiffies, timeout) && !(inb_status(dev->base_addr) & ACRF)); | ||
270 | } while (inb_status(dev->base_addr) & ACRF); | ||
271 | set_hsf(dev, HSF_PCB_NAK); | ||
272 | } | ||
273 | outb_control(adapter->hcr_val | ATTN | DIR, dev); | ||
274 | mdelay(10); | ||
275 | outb_control(adapter->hcr_val & ~ATTN, dev); | ||
276 | mdelay(10); | ||
277 | outb_control(adapter->hcr_val | FLSH, dev); | ||
278 | mdelay(10); | ||
279 | outb_control(adapter->hcr_val & ~FLSH, dev); | ||
280 | mdelay(10); | ||
281 | |||
282 | outb_control(orig_hcr, dev); | ||
283 | if (!start_receive(dev, &adapter->tx_pcb)) | ||
284 | pr_err("%s: start receive command failed\n", dev->name); | ||
285 | } | ||
286 | |||
287 | /* Check to make sure that a DMA transfer hasn't timed out. This should | ||
288 | * never happen in theory, but seems to occur occasionally if the card gets | ||
289 | * prodded at the wrong time. | ||
290 | */ | ||
291 | static inline void check_3c505_dma(struct net_device *dev) | ||
292 | { | ||
293 | elp_device *adapter = netdev_priv(dev); | ||
294 | if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) { | ||
295 | unsigned long flags, f; | ||
296 | pr_err("%s: DMA %s timed out, %d bytes left\n", dev->name, | ||
297 | adapter->current_dma.direction ? "download" : "upload", | ||
298 | get_dma_residue(dev->dma)); | ||
299 | spin_lock_irqsave(&adapter->lock, flags); | ||
300 | adapter->dmaing = 0; | ||
301 | adapter->busy = 0; | ||
302 | |||
303 | f=claim_dma_lock(); | ||
304 | disable_dma(dev->dma); | ||
305 | release_dma_lock(f); | ||
306 | |||
307 | if (adapter->rx_active) | ||
308 | adapter->rx_active--; | ||
309 | outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev); | ||
310 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
311 | } | ||
312 | } | ||
313 | |||
314 | /* Primitive functions used by send_pcb() */ | ||
315 | static inline bool send_pcb_slow(unsigned int base_addr, unsigned char byte) | ||
316 | { | ||
317 | unsigned long timeout; | ||
318 | outb_command(byte, base_addr); | ||
319 | for (timeout = jiffies + 5*HZ/100; time_before(jiffies, timeout);) { | ||
320 | if (inb_status(base_addr) & HCRE) | ||
321 | return false; | ||
322 | } | ||
323 | pr_warning("3c505: send_pcb_slow timed out\n"); | ||
324 | return true; | ||
325 | } | ||
326 | |||
327 | static inline bool send_pcb_fast(unsigned int base_addr, unsigned char byte) | ||
328 | { | ||
329 | unsigned int timeout; | ||
330 | outb_command(byte, base_addr); | ||
331 | for (timeout = 0; timeout < 40000; timeout++) { | ||
332 | if (inb_status(base_addr) & HCRE) | ||
333 | return false; | ||
334 | } | ||
335 | pr_warning("3c505: send_pcb_fast timed out\n"); | ||
336 | return true; | ||
337 | } | ||
338 | |||
339 | /* Check to see if the receiver needs restarting, and kick it if so */ | ||
340 | static inline void prime_rx(struct net_device *dev) | ||
341 | { | ||
342 | elp_device *adapter = netdev_priv(dev); | ||
343 | while (adapter->rx_active < ELP_RX_PCBS && netif_running(dev)) { | ||
344 | if (!start_receive(dev, &adapter->itx_pcb)) | ||
345 | break; | ||
346 | } | ||
347 | } | ||
348 | |||
349 | /***************************************************************** | ||
350 | * | ||
351 | * send_pcb | ||
352 | * Send a PCB to the adapter. | ||
353 | * | ||
354 | * output byte to command reg --<--+ | ||
355 | * wait until HCRE is non zero | | ||
356 | * loop until all bytes sent -->--+ | ||
357 | * set HSF1 and HSF2 to 1 | ||
358 | * output pcb length | ||
359 | * wait until ASF give ACK or NAK | ||
360 | * set HSF1 and HSF2 to 0 | ||
361 | * | ||
362 | *****************************************************************/ | ||
363 | |||
364 | /* This can be quite slow -- the adapter is allowed to take up to 40ms | ||
365 | * to respond to the initial interrupt. | ||
366 | * | ||
367 | * We run initially with interrupts turned on, but with a semaphore set | ||
368 | * so that nobody tries to re-enter this code. Once the first byte has | ||
369 | * gone through, we turn interrupts off and then send the others (the | ||
370 | * timeout is reduced to 500us). | ||
371 | */ | ||
372 | |||
373 | static bool send_pcb(struct net_device *dev, pcb_struct * pcb) | ||
374 | { | ||
375 | int i; | ||
376 | unsigned long timeout; | ||
377 | elp_device *adapter = netdev_priv(dev); | ||
378 | unsigned long flags; | ||
379 | |||
380 | check_3c505_dma(dev); | ||
381 | |||
382 | if (adapter->dmaing && adapter->current_dma.direction == 0) | ||
383 | return false; | ||
384 | |||
385 | /* Avoid contention */ | ||
386 | if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) { | ||
387 | if (elp_debug >= 3) { | ||
388 | pr_debug("%s: send_pcb entered while threaded\n", dev->name); | ||
389 | } | ||
390 | return false; | ||
391 | } | ||
392 | /* | ||
393 | * load each byte into the command register and | ||
394 | * wait for the HCRE bit to indicate the adapter | ||
395 | * had read the byte | ||
396 | */ | ||
397 | set_hsf(dev, 0); | ||
398 | |||
399 | if (send_pcb_slow(dev->base_addr, pcb->command)) | ||
400 | goto abort; | ||
401 | |||
402 | spin_lock_irqsave(&adapter->lock, flags); | ||
403 | |||
404 | if (send_pcb_fast(dev->base_addr, pcb->length)) | ||
405 | goto sti_abort; | ||
406 | |||
407 | for (i = 0; i < pcb->length; i++) { | ||
408 | if (send_pcb_fast(dev->base_addr, pcb->data.raw[i])) | ||
409 | goto sti_abort; | ||
410 | } | ||
411 | |||
412 | outb_control(adapter->hcr_val | 3, dev); /* signal end of PCB */ | ||
413 | outb_command(2 + pcb->length, dev->base_addr); | ||
414 | |||
415 | /* now wait for the acknowledgement */ | ||
416 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
417 | |||
418 | for (timeout = jiffies + 5*HZ/100; time_before(jiffies, timeout);) { | ||
419 | switch (GET_ASF(dev->base_addr)) { | ||
420 | case ASF_PCB_ACK: | ||
421 | adapter->send_pcb_semaphore = 0; | ||
422 | return true; | ||
423 | |||
424 | case ASF_PCB_NAK: | ||
425 | #ifdef ELP_DEBUG | ||
426 | pr_debug("%s: send_pcb got NAK\n", dev->name); | ||
427 | #endif | ||
428 | goto abort; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | if (elp_debug >= 1) | ||
433 | pr_debug("%s: timeout waiting for PCB acknowledge (status %02x)\n", | ||
434 | dev->name, inb_status(dev->base_addr)); | ||
435 | goto abort; | ||
436 | |||
437 | sti_abort: | ||
438 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
439 | abort: | ||
440 | adapter->send_pcb_semaphore = 0; | ||
441 | return false; | ||
442 | } | ||
443 | |||
444 | |||
445 | /***************************************************************** | ||
446 | * | ||
447 | * receive_pcb | ||
448 | * Read a PCB from the adapter | ||
449 | * | ||
450 | * wait for ACRF to be non-zero ---<---+ | ||
451 | * input a byte | | ||
452 | * if ASF1 and ASF2 were not both one | | ||
453 | * before byte was read, loop --->---+ | ||
454 | * set HSF1 and HSF2 for ack | ||
455 | * | ||
456 | *****************************************************************/ | ||
457 | |||
458 | static bool receive_pcb(struct net_device *dev, pcb_struct * pcb) | ||
459 | { | ||
460 | int i, j; | ||
461 | int total_length; | ||
462 | int stat; | ||
463 | unsigned long timeout; | ||
464 | unsigned long flags; | ||
465 | |||
466 | elp_device *adapter = netdev_priv(dev); | ||
467 | |||
468 | set_hsf(dev, 0); | ||
469 | |||
470 | /* get the command code */ | ||
471 | timeout = jiffies + 2*HZ/100; | ||
472 | while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout)); | ||
473 | if (time_after_eq(jiffies, timeout)) { | ||
474 | TIMEOUT_MSG(__LINE__); | ||
475 | return false; | ||
476 | } | ||
477 | pcb->command = inb_command(dev->base_addr); | ||
478 | |||
479 | /* read the data length */ | ||
480 | timeout = jiffies + 3*HZ/100; | ||
481 | while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout)); | ||
482 | if (time_after_eq(jiffies, timeout)) { | ||
483 | TIMEOUT_MSG(__LINE__); | ||
484 | pr_info("%s: status %02x\n", dev->name, stat); | ||
485 | return false; | ||
486 | } | ||
487 | pcb->length = inb_command(dev->base_addr); | ||
488 | |||
489 | if (pcb->length > MAX_PCB_DATA) { | ||
490 | INVALID_PCB_MSG(pcb->length); | ||
491 | adapter_reset(dev); | ||
492 | return false; | ||
493 | } | ||
494 | /* read the data */ | ||
495 | spin_lock_irqsave(&adapter->lock, flags); | ||
496 | for (i = 0; i < MAX_PCB_DATA; i++) { | ||
497 | for (j = 0; j < 20000; j++) { | ||
498 | stat = get_status(dev->base_addr); | ||
499 | if (stat & ACRF) | ||
500 | break; | ||
501 | } | ||
502 | pcb->data.raw[i] = inb_command(dev->base_addr); | ||
503 | if ((stat & ASF_PCB_MASK) == ASF_PCB_END || j >= 20000) | ||
504 | break; | ||
505 | } | ||
506 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
507 | if (i >= MAX_PCB_DATA) { | ||
508 | INVALID_PCB_MSG(i); | ||
509 | return false; | ||
510 | } | ||
511 | if (j >= 20000) { | ||
512 | TIMEOUT_MSG(__LINE__); | ||
513 | return false; | ||
514 | } | ||
515 | /* the last "data" byte was really the length! */ | ||
516 | total_length = pcb->data.raw[i]; | ||
517 | |||
518 | /* safety check total length vs data length */ | ||
519 | if (total_length != (pcb->length + 2)) { | ||
520 | if (elp_debug >= 2) | ||
521 | pr_warning("%s: mangled PCB received\n", dev->name); | ||
522 | set_hsf(dev, HSF_PCB_NAK); | ||
523 | return false; | ||
524 | } | ||
525 | |||
526 | if (pcb->command == CMD_RECEIVE_PACKET_COMPLETE) { | ||
527 | if (test_and_set_bit(0, (void *) &adapter->busy)) { | ||
528 | if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) { | ||
529 | set_hsf(dev, HSF_PCB_NAK); | ||
530 | pr_warning("%s: PCB rejected, transfer in progress and backlog full\n", dev->name); | ||
531 | pcb->command = 0; | ||
532 | return true; | ||
533 | } else { | ||
534 | pcb->command = 0xff; | ||
535 | } | ||
536 | } | ||
537 | } | ||
538 | set_hsf(dev, HSF_PCB_ACK); | ||
539 | return true; | ||
540 | } | ||
541 | |||
542 | /****************************************************** | ||
543 | * | ||
544 | * queue a receive command on the adapter so we will get an | ||
545 | * interrupt when a packet is received. | ||
546 | * | ||
547 | ******************************************************/ | ||
548 | |||
549 | static bool start_receive(struct net_device *dev, pcb_struct * tx_pcb) | ||
550 | { | ||
551 | bool status; | ||
552 | elp_device *adapter = netdev_priv(dev); | ||
553 | |||
554 | if (elp_debug >= 3) | ||
555 | pr_debug("%s: restarting receiver\n", dev->name); | ||
556 | tx_pcb->command = CMD_RECEIVE_PACKET; | ||
557 | tx_pcb->length = sizeof(struct Rcv_pkt); | ||
558 | tx_pcb->data.rcv_pkt.buf_seg | ||
559 | = tx_pcb->data.rcv_pkt.buf_ofs = 0; /* Unused */ | ||
560 | tx_pcb->data.rcv_pkt.buf_len = 1600; | ||
561 | tx_pcb->data.rcv_pkt.timeout = 0; /* set timeout to zero */ | ||
562 | status = send_pcb(dev, tx_pcb); | ||
563 | if (status) | ||
564 | adapter->rx_active++; | ||
565 | return status; | ||
566 | } | ||
567 | |||
568 | /****************************************************** | ||
569 | * | ||
570 | * extract a packet from the adapter | ||
571 | * this routine is only called from within the interrupt | ||
572 | * service routine, so no cli/sti calls are needed | ||
573 | * note that the length is always assumed to be even | ||
574 | * | ||
575 | ******************************************************/ | ||
576 | |||
577 | static void receive_packet(struct net_device *dev, int len) | ||
578 | { | ||
579 | int rlen; | ||
580 | elp_device *adapter = netdev_priv(dev); | ||
581 | void *target; | ||
582 | struct sk_buff *skb; | ||
583 | unsigned long flags; | ||
584 | |||
585 | rlen = (len + 1) & ~1; | ||
586 | skb = netdev_alloc_skb(dev, rlen + 2); | ||
587 | |||
588 | if (!skb) { | ||
589 | pr_warning("%s: memory squeeze, dropping packet\n", dev->name); | ||
590 | target = adapter->dma_buffer; | ||
591 | adapter->current_dma.target = NULL; | ||
592 | /* FIXME: stats */ | ||
593 | return; | ||
594 | } | ||
595 | |||
596 | skb_reserve(skb, 2); | ||
597 | target = skb_put(skb, rlen); | ||
598 | if ((unsigned long)(target + rlen) >= MAX_DMA_ADDRESS) { | ||
599 | adapter->current_dma.target = target; | ||
600 | target = adapter->dma_buffer; | ||
601 | } else { | ||
602 | adapter->current_dma.target = NULL; | ||
603 | } | ||
604 | |||
605 | /* if this happens, we die */ | ||
606 | if (test_and_set_bit(0, (void *) &adapter->dmaing)) | ||
607 | pr_err("%s: rx blocked, DMA in progress, dir %d\n", | ||
608 | dev->name, adapter->current_dma.direction); | ||
609 | |||
610 | adapter->current_dma.direction = 0; | ||
611 | adapter->current_dma.length = rlen; | ||
612 | adapter->current_dma.skb = skb; | ||
613 | adapter->current_dma.start_time = jiffies; | ||
614 | |||
615 | outb_control(adapter->hcr_val | DIR | TCEN | DMAE, dev); | ||
616 | |||
617 | flags=claim_dma_lock(); | ||
618 | disable_dma(dev->dma); | ||
619 | clear_dma_ff(dev->dma); | ||
620 | set_dma_mode(dev->dma, 0x04); /* dma read */ | ||
621 | set_dma_addr(dev->dma, isa_virt_to_bus(target)); | ||
622 | set_dma_count(dev->dma, rlen); | ||
623 | enable_dma(dev->dma); | ||
624 | release_dma_lock(flags); | ||
625 | |||
626 | if (elp_debug >= 3) { | ||
627 | pr_debug("%s: rx DMA transfer started\n", dev->name); | ||
628 | } | ||
629 | |||
630 | if (adapter->rx_active) | ||
631 | adapter->rx_active--; | ||
632 | |||
633 | if (!adapter->busy) | ||
634 | pr_warning("%s: receive_packet called, busy not set.\n", dev->name); | ||
635 | } | ||
636 | |||
637 | /****************************************************** | ||
638 | * | ||
639 | * interrupt handler | ||
640 | * | ||
641 | ******************************************************/ | ||
642 | |||
643 | static irqreturn_t elp_interrupt(int irq, void *dev_id) | ||
644 | { | ||
645 | int len; | ||
646 | int dlen; | ||
647 | int icount = 0; | ||
648 | struct net_device *dev = dev_id; | ||
649 | elp_device *adapter = netdev_priv(dev); | ||
650 | unsigned long timeout; | ||
651 | |||
652 | spin_lock(&adapter->lock); | ||
653 | |||
654 | do { | ||
655 | /* | ||
656 | * has a DMA transfer finished? | ||
657 | */ | ||
658 | if (inb_status(dev->base_addr) & DONE) { | ||
659 | if (!adapter->dmaing) | ||
660 | pr_warning("%s: phantom DMA completed\n", dev->name); | ||
661 | |||
662 | if (elp_debug >= 3) | ||
663 | pr_debug("%s: %s DMA complete, status %02x\n", dev->name, | ||
664 | adapter->current_dma.direction ? "tx" : "rx", | ||
665 | inb_status(dev->base_addr)); | ||
666 | |||
667 | outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev); | ||
668 | if (adapter->current_dma.direction) { | ||
669 | dev_kfree_skb_irq(adapter->current_dma.skb); | ||
670 | } else { | ||
671 | struct sk_buff *skb = adapter->current_dma.skb; | ||
672 | if (skb) { | ||
673 | if (adapter->current_dma.target) { | ||
674 | /* have already done the skb_put() */ | ||
675 | memcpy(adapter->current_dma.target, adapter->dma_buffer, adapter->current_dma.length); | ||
676 | } | ||
677 | skb->protocol = eth_type_trans(skb,dev); | ||
678 | dev->stats.rx_bytes += skb->len; | ||
679 | netif_rx(skb); | ||
680 | } | ||
681 | } | ||
682 | adapter->dmaing = 0; | ||
683 | if (adapter->rx_backlog.in != adapter->rx_backlog.out) { | ||
684 | int t = adapter->rx_backlog.length[adapter->rx_backlog.out]; | ||
685 | adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out); | ||
686 | if (elp_debug >= 2) | ||
687 | pr_debug("%s: receiving backlogged packet (%d)\n", dev->name, t); | ||
688 | receive_packet(dev, t); | ||
689 | } else { | ||
690 | adapter->busy = 0; | ||
691 | } | ||
692 | } else { | ||
693 | /* has one timed out? */ | ||
694 | check_3c505_dma(dev); | ||
695 | } | ||
696 | |||
697 | /* | ||
698 | * receive a PCB from the adapter | ||
699 | */ | ||
700 | timeout = jiffies + 3*HZ/100; | ||
701 | while ((inb_status(dev->base_addr) & ACRF) != 0 && time_before(jiffies, timeout)) { | ||
702 | if (receive_pcb(dev, &adapter->irx_pcb)) { | ||
703 | switch (adapter->irx_pcb.command) | ||
704 | { | ||
705 | case 0: | ||
706 | break; | ||
707 | /* | ||
708 | * received a packet - this must be handled fast | ||
709 | */ | ||
710 | case 0xff: | ||
711 | case CMD_RECEIVE_PACKET_COMPLETE: | ||
712 | /* if the device isn't open, don't pass packets up the stack */ | ||
713 | if (!netif_running(dev)) | ||
714 | break; | ||
715 | len = adapter->irx_pcb.data.rcv_resp.pkt_len; | ||
716 | dlen = adapter->irx_pcb.data.rcv_resp.buf_len; | ||
717 | if (adapter->irx_pcb.data.rcv_resp.timeout != 0) { | ||
718 | pr_err("%s: interrupt - packet not received correctly\n", dev->name); | ||
719 | } else { | ||
720 | if (elp_debug >= 3) { | ||
721 | pr_debug("%s: interrupt - packet received of length %i (%i)\n", | ||
722 | dev->name, len, dlen); | ||
723 | } | ||
724 | if (adapter->irx_pcb.command == 0xff) { | ||
725 | if (elp_debug >= 2) | ||
726 | pr_debug("%s: adding packet to backlog (len = %d)\n", | ||
727 | dev->name, dlen); | ||
728 | adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen; | ||
729 | adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in); | ||
730 | } else { | ||
731 | receive_packet(dev, dlen); | ||
732 | } | ||
733 | if (elp_debug >= 3) | ||
734 | pr_debug("%s: packet received\n", dev->name); | ||
735 | } | ||
736 | break; | ||
737 | |||
738 | /* | ||
739 | * 82586 configured correctly | ||
740 | */ | ||
741 | case CMD_CONFIGURE_82586_RESPONSE: | ||
742 | adapter->got[CMD_CONFIGURE_82586] = 1; | ||
743 | if (elp_debug >= 3) | ||
744 | pr_debug("%s: interrupt - configure response received\n", dev->name); | ||
745 | break; | ||
746 | |||
747 | /* | ||
748 | * Adapter memory configuration | ||
749 | */ | ||
750 | case CMD_CONFIGURE_ADAPTER_RESPONSE: | ||
751 | adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1; | ||
752 | if (elp_debug >= 3) | ||
753 | pr_debug("%s: Adapter memory configuration %s.\n", dev->name, | ||
754 | adapter->irx_pcb.data.failed ? "failed" : "succeeded"); | ||
755 | break; | ||
756 | |||
757 | /* | ||
758 | * Multicast list loading | ||
759 | */ | ||
760 | case CMD_LOAD_MULTICAST_RESPONSE: | ||
761 | adapter->got[CMD_LOAD_MULTICAST_LIST] = 1; | ||
762 | if (elp_debug >= 3) | ||
763 | pr_debug("%s: Multicast address list loading %s.\n", dev->name, | ||
764 | adapter->irx_pcb.data.failed ? "failed" : "succeeded"); | ||
765 | break; | ||
766 | |||
767 | /* | ||
768 | * Station address setting | ||
769 | */ | ||
770 | case CMD_SET_ADDRESS_RESPONSE: | ||
771 | adapter->got[CMD_SET_STATION_ADDRESS] = 1; | ||
772 | if (elp_debug >= 3) | ||
773 | pr_debug("%s: Ethernet address setting %s.\n", dev->name, | ||
774 | adapter->irx_pcb.data.failed ? "failed" : "succeeded"); | ||
775 | break; | ||
776 | |||
777 | |||
778 | /* | ||
779 | * received board statistics | ||
780 | */ | ||
781 | case CMD_NETWORK_STATISTICS_RESPONSE: | ||
782 | dev->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv; | ||
783 | dev->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit; | ||
784 | dev->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC; | ||
785 | dev->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align; | ||
786 | dev->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun; | ||
787 | dev->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res; | ||
788 | adapter->got[CMD_NETWORK_STATISTICS] = 1; | ||
789 | if (elp_debug >= 3) | ||
790 | pr_debug("%s: interrupt - statistics response received\n", dev->name); | ||
791 | break; | ||
792 | |||
793 | /* | ||
794 | * sent a packet | ||
795 | */ | ||
796 | case CMD_TRANSMIT_PACKET_COMPLETE: | ||
797 | if (elp_debug >= 3) | ||
798 | pr_debug("%s: interrupt - packet sent\n", dev->name); | ||
799 | if (!netif_running(dev)) | ||
800 | break; | ||
801 | switch (adapter->irx_pcb.data.xmit_resp.c_stat) { | ||
802 | case 0xffff: | ||
803 | dev->stats.tx_aborted_errors++; | ||
804 | pr_info("%s: transmit timed out, network cable problem?\n", dev->name); | ||
805 | break; | ||
806 | case 0xfffe: | ||
807 | dev->stats.tx_fifo_errors++; | ||
808 | pr_info("%s: transmit timed out, FIFO underrun\n", dev->name); | ||
809 | break; | ||
810 | } | ||
811 | netif_wake_queue(dev); | ||
812 | break; | ||
813 | |||
814 | /* | ||
815 | * some unknown PCB | ||
816 | */ | ||
817 | default: | ||
818 | pr_debug("%s: unknown PCB received - %2.2x\n", | ||
819 | dev->name, adapter->irx_pcb.command); | ||
820 | break; | ||
821 | } | ||
822 | } else { | ||
823 | pr_warning("%s: failed to read PCB on interrupt\n", dev->name); | ||
824 | adapter_reset(dev); | ||
825 | } | ||
826 | } | ||
827 | |||
828 | } while (icount++ < 5 && (inb_status(dev->base_addr) & (ACRF | DONE))); | ||
829 | |||
830 | prime_rx(dev); | ||
831 | |||
832 | /* | ||
833 | * indicate no longer in interrupt routine | ||
834 | */ | ||
835 | spin_unlock(&adapter->lock); | ||
836 | return IRQ_HANDLED; | ||
837 | } | ||
838 | |||
839 | |||
840 | /****************************************************** | ||
841 | * | ||
842 | * open the board | ||
843 | * | ||
844 | ******************************************************/ | ||
845 | |||
846 | static int elp_open(struct net_device *dev) | ||
847 | { | ||
848 | elp_device *adapter = netdev_priv(dev); | ||
849 | int retval; | ||
850 | |||
851 | if (elp_debug >= 3) | ||
852 | pr_debug("%s: request to open device\n", dev->name); | ||
853 | |||
854 | /* | ||
855 | * make sure we actually found the device | ||
856 | */ | ||
857 | if (adapter == NULL) { | ||
858 | pr_err("%s: Opening a non-existent physical device\n", dev->name); | ||
859 | return -EAGAIN; | ||
860 | } | ||
861 | /* | ||
862 | * disable interrupts on the board | ||
863 | */ | ||
864 | outb_control(0, dev); | ||
865 | |||
866 | /* | ||
867 | * clear any pending interrupts | ||
868 | */ | ||
869 | inb_command(dev->base_addr); | ||
870 | adapter_reset(dev); | ||
871 | |||
872 | /* | ||
873 | * no receive PCBs active | ||
874 | */ | ||
875 | adapter->rx_active = 0; | ||
876 | |||
877 | adapter->busy = 0; | ||
878 | adapter->send_pcb_semaphore = 0; | ||
879 | adapter->rx_backlog.in = 0; | ||
880 | adapter->rx_backlog.out = 0; | ||
881 | |||
882 | spin_lock_init(&adapter->lock); | ||
883 | |||
884 | /* | ||
885 | * install our interrupt service routine | ||
886 | */ | ||
887 | if ((retval = request_irq(dev->irq, elp_interrupt, 0, dev->name, dev))) { | ||
888 | pr_err("%s: could not allocate IRQ%d\n", dev->name, dev->irq); | ||
889 | return retval; | ||
890 | } | ||
891 | if ((retval = request_dma(dev->dma, dev->name))) { | ||
892 | free_irq(dev->irq, dev); | ||
893 | pr_err("%s: could not allocate DMA%d channel\n", dev->name, dev->dma); | ||
894 | return retval; | ||
895 | } | ||
896 | adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE); | ||
897 | if (!adapter->dma_buffer) { | ||
898 | pr_err("%s: could not allocate DMA buffer\n", dev->name); | ||
899 | free_dma(dev->dma); | ||
900 | free_irq(dev->irq, dev); | ||
901 | return -ENOMEM; | ||
902 | } | ||
903 | adapter->dmaing = 0; | ||
904 | |||
905 | /* | ||
906 | * enable interrupts on the board | ||
907 | */ | ||
908 | outb_control(CMDE, dev); | ||
909 | |||
910 | /* | ||
911 | * configure adapter memory: we need 10 multicast addresses, default==0 | ||
912 | */ | ||
913 | if (elp_debug >= 3) | ||
914 | pr_debug("%s: sending 3c505 memory configuration command\n", dev->name); | ||
915 | adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY; | ||
916 | adapter->tx_pcb.data.memconf.cmd_q = 10; | ||
917 | adapter->tx_pcb.data.memconf.rcv_q = 20; | ||
918 | adapter->tx_pcb.data.memconf.mcast = 10; | ||
919 | adapter->tx_pcb.data.memconf.frame = 20; | ||
920 | adapter->tx_pcb.data.memconf.rcv_b = 20; | ||
921 | adapter->tx_pcb.data.memconf.progs = 0; | ||
922 | adapter->tx_pcb.length = sizeof(struct Memconf); | ||
923 | adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0; | ||
924 | if (!send_pcb(dev, &adapter->tx_pcb)) | ||
925 | pr_err("%s: couldn't send memory configuration command\n", dev->name); | ||
926 | else { | ||
927 | unsigned long timeout = jiffies + TIMEOUT; | ||
928 | while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && time_before(jiffies, timeout)); | ||
929 | if (time_after_eq(jiffies, timeout)) | ||
930 | TIMEOUT_MSG(__LINE__); | ||
931 | } | ||
932 | |||
933 | |||
934 | /* | ||
935 | * configure adapter to receive broadcast messages and wait for response | ||
936 | */ | ||
937 | if (elp_debug >= 3) | ||
938 | pr_debug("%s: sending 82586 configure command\n", dev->name); | ||
939 | adapter->tx_pcb.command = CMD_CONFIGURE_82586; | ||
940 | adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD; | ||
941 | adapter->tx_pcb.length = 2; | ||
942 | adapter->got[CMD_CONFIGURE_82586] = 0; | ||
943 | if (!send_pcb(dev, &adapter->tx_pcb)) | ||
944 | pr_err("%s: couldn't send 82586 configure command\n", dev->name); | ||
945 | else { | ||
946 | unsigned long timeout = jiffies + TIMEOUT; | ||
947 | while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout)); | ||
948 | if (time_after_eq(jiffies, timeout)) | ||
949 | TIMEOUT_MSG(__LINE__); | ||
950 | } | ||
951 | |||
952 | /* enable burst-mode DMA */ | ||
953 | /* outb(0x1, dev->base_addr + PORT_AUXDMA); */ | ||
954 | |||
955 | /* | ||
956 | * queue receive commands to provide buffering | ||
957 | */ | ||
958 | prime_rx(dev); | ||
959 | if (elp_debug >= 3) | ||
960 | pr_debug("%s: %d receive PCBs active\n", dev->name, adapter->rx_active); | ||
961 | |||
962 | /* | ||
963 | * device is now officially open! | ||
964 | */ | ||
965 | |||
966 | netif_start_queue(dev); | ||
967 | return 0; | ||
968 | } | ||
969 | |||
970 | |||
971 | /****************************************************** | ||
972 | * | ||
973 | * send a packet to the adapter | ||
974 | * | ||
975 | ******************************************************/ | ||
976 | |||
977 | static netdev_tx_t send_packet(struct net_device *dev, struct sk_buff *skb) | ||
978 | { | ||
979 | elp_device *adapter = netdev_priv(dev); | ||
980 | unsigned long target; | ||
981 | unsigned long flags; | ||
982 | |||
983 | /* | ||
984 | * make sure the length is even and no shorter than 60 bytes | ||
985 | */ | ||
986 | unsigned int nlen = (((skb->len < 60) ? 60 : skb->len) + 1) & (~1); | ||
987 | |||
988 | if (test_and_set_bit(0, (void *) &adapter->busy)) { | ||
989 | if (elp_debug >= 2) | ||
990 | pr_debug("%s: transmit blocked\n", dev->name); | ||
991 | return false; | ||
992 | } | ||
993 | |||
994 | dev->stats.tx_bytes += nlen; | ||
995 | |||
996 | /* | ||
997 | * send the adapter a transmit packet command. Ignore segment and offset | ||
998 | * and make sure the length is even | ||
999 | */ | ||
1000 | adapter->tx_pcb.command = CMD_TRANSMIT_PACKET; | ||
1001 | adapter->tx_pcb.length = sizeof(struct Xmit_pkt); | ||
1002 | adapter->tx_pcb.data.xmit_pkt.buf_ofs | ||
1003 | = adapter->tx_pcb.data.xmit_pkt.buf_seg = 0; /* Unused */ | ||
1004 | adapter->tx_pcb.data.xmit_pkt.pkt_len = nlen; | ||
1005 | |||
1006 | if (!send_pcb(dev, &adapter->tx_pcb)) { | ||
1007 | adapter->busy = 0; | ||
1008 | return false; | ||
1009 | } | ||
1010 | /* if this happens, we die */ | ||
1011 | if (test_and_set_bit(0, (void *) &adapter->dmaing)) | ||
1012 | pr_debug("%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction); | ||
1013 | |||
1014 | adapter->current_dma.direction = 1; | ||
1015 | adapter->current_dma.start_time = jiffies; | ||
1016 | |||
1017 | if ((unsigned long)(skb->data + nlen) >= MAX_DMA_ADDRESS || nlen != skb->len) { | ||
1018 | skb_copy_from_linear_data(skb, adapter->dma_buffer, nlen); | ||
1019 | memset(adapter->dma_buffer+skb->len, 0, nlen-skb->len); | ||
1020 | target = isa_virt_to_bus(adapter->dma_buffer); | ||
1021 | } | ||
1022 | else { | ||
1023 | target = isa_virt_to_bus(skb->data); | ||
1024 | } | ||
1025 | adapter->current_dma.skb = skb; | ||
1026 | |||
1027 | flags=claim_dma_lock(); | ||
1028 | disable_dma(dev->dma); | ||
1029 | clear_dma_ff(dev->dma); | ||
1030 | set_dma_mode(dev->dma, 0x48); /* dma memory -> io */ | ||
1031 | set_dma_addr(dev->dma, target); | ||
1032 | set_dma_count(dev->dma, nlen); | ||
1033 | outb_control(adapter->hcr_val | DMAE | TCEN, dev); | ||
1034 | enable_dma(dev->dma); | ||
1035 | release_dma_lock(flags); | ||
1036 | |||
1037 | if (elp_debug >= 3) | ||
1038 | pr_debug("%s: DMA transfer started\n", dev->name); | ||
1039 | |||
1040 | return true; | ||
1041 | } | ||
1042 | |||
1043 | /* | ||
1044 | * The upper layer thinks we timed out | ||
1045 | */ | ||
1046 | |||
1047 | static void elp_timeout(struct net_device *dev) | ||
1048 | { | ||
1049 | int stat; | ||
1050 | |||
1051 | stat = inb_status(dev->base_addr); | ||
1052 | pr_warning("%s: transmit timed out, lost %s?\n", dev->name, | ||
1053 | (stat & ACRF) ? "interrupt" : "command"); | ||
1054 | if (elp_debug >= 1) | ||
1055 | pr_debug("%s: status %#02x\n", dev->name, stat); | ||
1056 | dev->trans_start = jiffies; /* prevent tx timeout */ | ||
1057 | dev->stats.tx_dropped++; | ||
1058 | netif_wake_queue(dev); | ||
1059 | } | ||
1060 | |||
1061 | /****************************************************** | ||
1062 | * | ||
1063 | * start the transmitter | ||
1064 | * return 0 if sent OK, else return 1 | ||
1065 | * | ||
1066 | ******************************************************/ | ||
1067 | |||
1068 | static netdev_tx_t elp_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
1069 | { | ||
1070 | unsigned long flags; | ||
1071 | elp_device *adapter = netdev_priv(dev); | ||
1072 | |||
1073 | spin_lock_irqsave(&adapter->lock, flags); | ||
1074 | check_3c505_dma(dev); | ||
1075 | |||
1076 | if (elp_debug >= 3) | ||
1077 | pr_debug("%s: request to send packet of length %d\n", dev->name, (int) skb->len); | ||
1078 | |||
1079 | netif_stop_queue(dev); | ||
1080 | |||
1081 | /* | ||
1082 | * send the packet at skb->data for skb->len | ||
1083 | */ | ||
1084 | if (!send_packet(dev, skb)) { | ||
1085 | if (elp_debug >= 2) { | ||
1086 | pr_debug("%s: failed to transmit packet\n", dev->name); | ||
1087 | } | ||
1088 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
1089 | return NETDEV_TX_BUSY; | ||
1090 | } | ||
1091 | if (elp_debug >= 3) | ||
1092 | pr_debug("%s: packet of length %d sent\n", dev->name, (int) skb->len); | ||
1093 | |||
1094 | prime_rx(dev); | ||
1095 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
1096 | netif_start_queue(dev); | ||
1097 | return NETDEV_TX_OK; | ||
1098 | } | ||
1099 | |||
1100 | /****************************************************** | ||
1101 | * | ||
1102 | * return statistics on the board | ||
1103 | * | ||
1104 | ******************************************************/ | ||
1105 | |||
1106 | static struct net_device_stats *elp_get_stats(struct net_device *dev) | ||
1107 | { | ||
1108 | elp_device *adapter = netdev_priv(dev); | ||
1109 | |||
1110 | if (elp_debug >= 3) | ||
1111 | pr_debug("%s: request for stats\n", dev->name); | ||
1112 | |||
1113 | /* If the device is closed, just return the latest stats we have, | ||
1114 | - we cannot ask from the adapter without interrupts */ | ||
1115 | if (!netif_running(dev)) | ||
1116 | return &dev->stats; | ||
1117 | |||
1118 | /* send a get statistics command to the board */ | ||
1119 | adapter->tx_pcb.command = CMD_NETWORK_STATISTICS; | ||
1120 | adapter->tx_pcb.length = 0; | ||
1121 | adapter->got[CMD_NETWORK_STATISTICS] = 0; | ||
1122 | if (!send_pcb(dev, &adapter->tx_pcb)) | ||
1123 | pr_err("%s: couldn't send get statistics command\n", dev->name); | ||
1124 | else { | ||
1125 | unsigned long timeout = jiffies + TIMEOUT; | ||
1126 | while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout)); | ||
1127 | if (time_after_eq(jiffies, timeout)) { | ||
1128 | TIMEOUT_MSG(__LINE__); | ||
1129 | return &dev->stats; | ||
1130 | } | ||
1131 | } | ||
1132 | |||
1133 | /* statistics are now up to date */ | ||
1134 | return &dev->stats; | ||
1135 | } | ||
1136 | |||
1137 | |||
1138 | static void netdev_get_drvinfo(struct net_device *dev, | ||
1139 | struct ethtool_drvinfo *info) | ||
1140 | { | ||
1141 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); | ||
1142 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); | ||
1143 | snprintf(info->bus_info, sizeof(info->bus_info), "ISA 0x%lx", | ||
1144 | dev->base_addr); | ||
1145 | } | ||
1146 | |||
1147 | static u32 netdev_get_msglevel(struct net_device *dev) | ||
1148 | { | ||
1149 | return debug; | ||
1150 | } | ||
1151 | |||
1152 | static void netdev_set_msglevel(struct net_device *dev, u32 level) | ||
1153 | { | ||
1154 | debug = level; | ||
1155 | } | ||
1156 | |||
1157 | static const struct ethtool_ops netdev_ethtool_ops = { | ||
1158 | .get_drvinfo = netdev_get_drvinfo, | ||
1159 | .get_msglevel = netdev_get_msglevel, | ||
1160 | .set_msglevel = netdev_set_msglevel, | ||
1161 | }; | ||
1162 | |||
1163 | /****************************************************** | ||
1164 | * | ||
1165 | * close the board | ||
1166 | * | ||
1167 | ******************************************************/ | ||
1168 | |||
1169 | static int elp_close(struct net_device *dev) | ||
1170 | { | ||
1171 | elp_device *adapter = netdev_priv(dev); | ||
1172 | |||
1173 | if (elp_debug >= 3) | ||
1174 | pr_debug("%s: request to close device\n", dev->name); | ||
1175 | |||
1176 | netif_stop_queue(dev); | ||
1177 | |||
1178 | /* Someone may request the device statistic information even when | ||
1179 | * the interface is closed. The following will update the statistics | ||
1180 | * structure in the driver, so we'll be able to give current statistics. | ||
1181 | */ | ||
1182 | (void) elp_get_stats(dev); | ||
1183 | |||
1184 | /* | ||
1185 | * disable interrupts on the board | ||
1186 | */ | ||
1187 | outb_control(0, dev); | ||
1188 | |||
1189 | /* | ||
1190 | * release the IRQ | ||
1191 | */ | ||
1192 | free_irq(dev->irq, dev); | ||
1193 | |||
1194 | free_dma(dev->dma); | ||
1195 | free_pages((unsigned long) adapter->dma_buffer, get_order(DMA_BUFFER_SIZE)); | ||
1196 | |||
1197 | return 0; | ||
1198 | } | ||
1199 | |||
1200 | |||
1201 | /************************************************************ | ||
1202 | * | ||
1203 | * Set multicast list | ||
1204 | * num_addrs==0: clear mc_list | ||
1205 | * num_addrs==-1: set promiscuous mode | ||
1206 | * num_addrs>0: set mc_list | ||
1207 | * | ||
1208 | ************************************************************/ | ||
1209 | |||
1210 | static void elp_set_mc_list(struct net_device *dev) | ||
1211 | { | ||
1212 | elp_device *adapter = netdev_priv(dev); | ||
1213 | struct netdev_hw_addr *ha; | ||
1214 | int i; | ||
1215 | unsigned long flags; | ||
1216 | |||
1217 | if (elp_debug >= 3) | ||
1218 | pr_debug("%s: request to set multicast list\n", dev->name); | ||
1219 | |||
1220 | spin_lock_irqsave(&adapter->lock, flags); | ||
1221 | |||
1222 | if (!(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) { | ||
1223 | /* send a "load multicast list" command to the board, max 10 addrs/cmd */ | ||
1224 | /* if num_addrs==0 the list will be cleared */ | ||
1225 | adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST; | ||
1226 | adapter->tx_pcb.length = 6 * netdev_mc_count(dev); | ||
1227 | i = 0; | ||
1228 | netdev_for_each_mc_addr(ha, dev) | ||
1229 | memcpy(adapter->tx_pcb.data.multicast[i++], | ||
1230 | ha->addr, 6); | ||
1231 | adapter->got[CMD_LOAD_MULTICAST_LIST] = 0; | ||
1232 | if (!send_pcb(dev, &adapter->tx_pcb)) | ||
1233 | pr_err("%s: couldn't send set_multicast command\n", dev->name); | ||
1234 | else { | ||
1235 | unsigned long timeout = jiffies + TIMEOUT; | ||
1236 | while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout)); | ||
1237 | if (time_after_eq(jiffies, timeout)) { | ||
1238 | TIMEOUT_MSG(__LINE__); | ||
1239 | } | ||
1240 | } | ||
1241 | if (!netdev_mc_empty(dev)) | ||
1242 | adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI; | ||
1243 | else /* num_addrs == 0 */ | ||
1244 | adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD; | ||
1245 | } else | ||
1246 | adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_PROMISC; | ||
1247 | /* | ||
1248 | * configure adapter to receive messages (as specified above) | ||
1249 | * and wait for response | ||
1250 | */ | ||
1251 | if (elp_debug >= 3) | ||
1252 | pr_debug("%s: sending 82586 configure command\n", dev->name); | ||
1253 | adapter->tx_pcb.command = CMD_CONFIGURE_82586; | ||
1254 | adapter->tx_pcb.length = 2; | ||
1255 | adapter->got[CMD_CONFIGURE_82586] = 0; | ||
1256 | if (!send_pcb(dev, &adapter->tx_pcb)) | ||
1257 | { | ||
1258 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
1259 | pr_err("%s: couldn't send 82586 configure command\n", dev->name); | ||
1260 | } | ||
1261 | else { | ||
1262 | unsigned long timeout = jiffies + TIMEOUT; | ||
1263 | spin_unlock_irqrestore(&adapter->lock, flags); | ||
1264 | while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout)); | ||
1265 | if (time_after_eq(jiffies, timeout)) | ||
1266 | TIMEOUT_MSG(__LINE__); | ||
1267 | } | ||
1268 | } | ||
1269 | |||
1270 | /************************************************************ | ||
1271 | * | ||
1272 | * A couple of tests to see if there's 3C505 or not | ||
1273 | * Called only by elp_autodetect | ||
1274 | ************************************************************/ | ||
1275 | |||
1276 | static int __init elp_sense(struct net_device *dev) | ||
1277 | { | ||
1278 | int addr = dev->base_addr; | ||
1279 | const char *name = dev->name; | ||
1280 | byte orig_HSR; | ||
1281 | |||
1282 | if (!request_region(addr, ELP_IO_EXTENT, "3c505")) | ||
1283 | return -ENODEV; | ||
1284 | |||
1285 | orig_HSR = inb_status(addr); | ||
1286 | |||
1287 | if (elp_debug > 0) | ||
1288 | pr_debug(search_msg, name, addr); | ||
1289 | |||
1290 | if (orig_HSR == 0xff) { | ||
1291 | if (elp_debug > 0) | ||
1292 | pr_cont(notfound_msg, 1); | ||
1293 | goto out; | ||
1294 | } | ||
1295 | |||
1296 | /* Wait for a while; the adapter may still be booting up */ | ||
1297 | if (elp_debug > 0) | ||
1298 | pr_cont(stilllooking_msg); | ||
1299 | |||
1300 | if (orig_HSR & DIR) { | ||
1301 | /* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */ | ||
1302 | outb(0, dev->base_addr + PORT_CONTROL); | ||
1303 | msleep(300); | ||
1304 | if (inb_status(addr) & DIR) { | ||
1305 | if (elp_debug > 0) | ||
1306 | pr_cont(notfound_msg, 2); | ||
1307 | goto out; | ||
1308 | } | ||
1309 | } else { | ||
1310 | /* If HCR.DIR is down, we pull it up. HSR.DIR should follow. */ | ||
1311 | outb(DIR, dev->base_addr + PORT_CONTROL); | ||
1312 | msleep(300); | ||
1313 | if (!(inb_status(addr) & DIR)) { | ||
1314 | if (elp_debug > 0) | ||
1315 | pr_cont(notfound_msg, 3); | ||
1316 | goto out; | ||
1317 | } | ||
1318 | } | ||
1319 | /* | ||
1320 | * It certainly looks like a 3c505. | ||
1321 | */ | ||
1322 | if (elp_debug > 0) | ||
1323 | pr_cont(found_msg); | ||
1324 | |||
1325 | return 0; | ||
1326 | out: | ||
1327 | release_region(addr, ELP_IO_EXTENT); | ||
1328 | return -ENODEV; | ||
1329 | } | ||
1330 | |||
1331 | /************************************************************* | ||
1332 | * | ||
1333 | * Search through addr_list[] and try to find a 3C505 | ||
1334 | * Called only by eplus_probe | ||
1335 | *************************************************************/ | ||
1336 | |||
1337 | static int __init elp_autodetect(struct net_device *dev) | ||
1338 | { | ||
1339 | int idx = 0; | ||
1340 | |||
1341 | /* if base address set, then only check that address | ||
1342 | otherwise, run through the table */ | ||
1343 | if (dev->base_addr != 0) { /* dev->base_addr == 0 ==> plain autodetect */ | ||
1344 | if (elp_sense(dev) == 0) | ||
1345 | return dev->base_addr; | ||
1346 | } else | ||
1347 | while ((dev->base_addr = addr_list[idx++])) { | ||
1348 | if (elp_sense(dev) == 0) | ||
1349 | return dev->base_addr; | ||
1350 | } | ||
1351 | |||
1352 | /* could not find an adapter */ | ||
1353 | if (elp_debug > 0) | ||
1354 | pr_debug(couldnot_msg, dev->name); | ||
1355 | |||
1356 | return 0; /* Because of this, the layer above will return -ENODEV */ | ||
1357 | } | ||
1358 | |||
1359 | static const struct net_device_ops elp_netdev_ops = { | ||
1360 | .ndo_open = elp_open, | ||
1361 | .ndo_stop = elp_close, | ||
1362 | .ndo_get_stats = elp_get_stats, | ||
1363 | .ndo_start_xmit = elp_start_xmit, | ||
1364 | .ndo_tx_timeout = elp_timeout, | ||
1365 | .ndo_set_rx_mode = elp_set_mc_list, | ||
1366 | .ndo_change_mtu = eth_change_mtu, | ||
1367 | .ndo_set_mac_address = eth_mac_addr, | ||
1368 | .ndo_validate_addr = eth_validate_addr, | ||
1369 | }; | ||
1370 | |||
1371 | /****************************************************** | ||
1372 | * | ||
1373 | * probe for an Etherlink Plus board at the specified address | ||
1374 | * | ||
1375 | ******************************************************/ | ||
1376 | |||
1377 | /* There are three situations we need to be able to detect here: | ||
1378 | |||
1379 | * a) the card is idle | ||
1380 | * b) the card is still booting up | ||
1381 | * c) the card is stuck in a strange state (some DOS drivers do this) | ||
1382 | * | ||
1383 | * In case (a), all is well. In case (b), we wait 10 seconds to see if the | ||
1384 | * card finishes booting, and carry on if so. In case (c), we do a hard reset, | ||
1385 | * loop round, and hope for the best. | ||
1386 | * | ||
1387 | * This is all very unpleasant, but hopefully avoids the problems with the old | ||
1388 | * probe code (which had a 15-second delay if the card was idle, and didn't | ||
1389 | * work at all if it was in a weird state). | ||
1390 | */ | ||
1391 | |||
1392 | static int __init elplus_setup(struct net_device *dev) | ||
1393 | { | ||
1394 | elp_device *adapter = netdev_priv(dev); | ||
1395 | int i, tries, tries1, okay; | ||
1396 | unsigned long timeout; | ||
1397 | unsigned long cookie = 0; | ||
1398 | int err = -ENODEV; | ||
1399 | |||
1400 | /* | ||
1401 | * setup adapter structure | ||
1402 | */ | ||
1403 | |||
1404 | dev->base_addr = elp_autodetect(dev); | ||
1405 | if (!dev->base_addr) | ||
1406 | return -ENODEV; | ||
1407 | |||
1408 | adapter->send_pcb_semaphore = 0; | ||
1409 | |||
1410 | for (tries1 = 0; tries1 < 3; tries1++) { | ||
1411 | outb_control((adapter->hcr_val | CMDE) & ~DIR, dev); | ||
1412 | /* First try to write just one byte, to see if the card is | ||
1413 | * responding at all normally. | ||
1414 | */ | ||
1415 | timeout = jiffies + 5*HZ/100; | ||
1416 | okay = 0; | ||
1417 | while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE)); | ||
1418 | if ((inb_status(dev->base_addr) & HCRE)) { | ||
1419 | outb_command(0, dev->base_addr); /* send a spurious byte */ | ||
1420 | timeout = jiffies + 5*HZ/100; | ||
1421 | while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE)); | ||
1422 | if (inb_status(dev->base_addr) & HCRE) | ||
1423 | okay = 1; | ||
1424 | } | ||
1425 | if (!okay) { | ||
1426 | /* Nope, it's ignoring the command register. This means that | ||
1427 | * either it's still booting up, or it's died. | ||
1428 | */ | ||
1429 | pr_err("%s: command register wouldn't drain, ", dev->name); | ||
1430 | if ((inb_status(dev->base_addr) & 7) == 3) { | ||
1431 | /* If the adapter status is 3, it *could* still be booting. | ||
1432 | * Give it the benefit of the doubt for 10 seconds. | ||
1433 | */ | ||
1434 | pr_cont("assuming 3c505 still starting\n"); | ||
1435 | timeout = jiffies + 10*HZ; | ||
1436 | while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7)); | ||
1437 | if (inb_status(dev->base_addr) & 7) { | ||
1438 | pr_err("%s: 3c505 failed to start\n", dev->name); | ||
1439 | } else { | ||
1440 | okay = 1; /* It started */ | ||
1441 | } | ||
1442 | } else { | ||
1443 | /* Otherwise, it must just be in a strange | ||
1444 | * state. We probably need to kick it. | ||
1445 | */ | ||
1446 | pr_cont("3c505 is sulking\n"); | ||
1447 | } | ||
1448 | } | ||
1449 | for (tries = 0; tries < 5 && okay; tries++) { | ||
1450 | |||
1451 | /* | ||
1452 | * Try to set the Ethernet address, to make sure that the board | ||
1453 | * is working. | ||
1454 | */ | ||
1455 | adapter->tx_pcb.command = CMD_STATION_ADDRESS; | ||
1456 | adapter->tx_pcb.length = 0; | ||
1457 | cookie = probe_irq_on(); | ||
1458 | if (!send_pcb(dev, &adapter->tx_pcb)) { | ||
1459 | pr_err("%s: could not send first PCB\n", dev->name); | ||
1460 | probe_irq_off(cookie); | ||
1461 | continue; | ||
1462 | } | ||
1463 | if (!receive_pcb(dev, &adapter->rx_pcb)) { | ||
1464 | pr_err("%s: could not read first PCB\n", dev->name); | ||
1465 | probe_irq_off(cookie); | ||
1466 | continue; | ||
1467 | } | ||
1468 | if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) || | ||
1469 | (adapter->rx_pcb.length != 6)) { | ||
1470 | pr_err("%s: first PCB wrong (%d, %d)\n", dev->name, | ||
1471 | adapter->rx_pcb.command, adapter->rx_pcb.length); | ||
1472 | probe_irq_off(cookie); | ||
1473 | continue; | ||
1474 | } | ||
1475 | goto okay; | ||
1476 | } | ||
1477 | /* It's broken. Do a hard reset to re-initialise the board, | ||
1478 | * and try again. | ||
1479 | */ | ||
1480 | pr_info("%s: resetting adapter\n", dev->name); | ||
1481 | outb_control(adapter->hcr_val | FLSH | ATTN, dev); | ||
1482 | outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev); | ||
1483 | } | ||
1484 | pr_err("%s: failed to initialise 3c505\n", dev->name); | ||
1485 | goto out; | ||
1486 | |||
1487 | okay: | ||
1488 | if (dev->irq) { /* Is there a preset IRQ? */ | ||
1489 | int rpt = probe_irq_off(cookie); | ||
1490 | if (dev->irq != rpt) { | ||
1491 | pr_warning("%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt); | ||
1492 | } | ||
1493 | /* if dev->irq == probe_irq_off(cookie), all is well */ | ||
1494 | } else /* No preset IRQ; just use what we can detect */ | ||
1495 | dev->irq = probe_irq_off(cookie); | ||
1496 | switch (dev->irq) { /* Legal, sane? */ | ||
1497 | case 0: | ||
1498 | pr_err("%s: IRQ probe failed: check 3c505 jumpers.\n", | ||
1499 | dev->name); | ||
1500 | goto out; | ||
1501 | case 1: | ||
1502 | case 6: | ||
1503 | case 8: | ||
1504 | case 13: | ||
1505 | pr_err("%s: Impossible IRQ %d reported by probe_irq_off().\n", | ||
1506 | dev->name, dev->irq); | ||
1507 | goto out; | ||
1508 | } | ||
1509 | /* | ||
1510 | * Now we have the IRQ number so we can disable the interrupts from | ||
1511 | * the board until the board is opened. | ||
1512 | */ | ||
1513 | outb_control(adapter->hcr_val & ~CMDE, dev); | ||
1514 | |||
1515 | /* | ||
1516 | * copy Ethernet address into structure | ||
1517 | */ | ||
1518 | for (i = 0; i < 6; i++) | ||
1519 | dev->dev_addr[i] = adapter->rx_pcb.data.eth_addr[i]; | ||
1520 | |||
1521 | /* find a DMA channel */ | ||
1522 | if (!dev->dma) { | ||
1523 | if (dev->mem_start) { | ||
1524 | dev->dma = dev->mem_start & 7; | ||
1525 | } | ||
1526 | else { | ||
1527 | pr_warning("%s: warning, DMA channel not specified, using default\n", dev->name); | ||
1528 | dev->dma = ELP_DMA; | ||
1529 | } | ||
1530 | } | ||
1531 | |||
1532 | /* | ||
1533 | * print remainder of startup message | ||
1534 | */ | ||
1535 | pr_info("%s: 3c505 at %#lx, irq %d, dma %d, addr %pM, ", | ||
1536 | dev->name, dev->base_addr, dev->irq, dev->dma, dev->dev_addr); | ||
1537 | /* | ||
1538 | * read more information from the adapter | ||
1539 | */ | ||
1540 | |||
1541 | adapter->tx_pcb.command = CMD_ADAPTER_INFO; | ||
1542 | adapter->tx_pcb.length = 0; | ||
1543 | if (!send_pcb(dev, &adapter->tx_pcb) || | ||
1544 | !receive_pcb(dev, &adapter->rx_pcb) || | ||
1545 | (adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) || | ||
1546 | (adapter->rx_pcb.length != 10)) { | ||
1547 | pr_cont("not responding to second PCB\n"); | ||
1548 | } | ||
1549 | pr_cont("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers, | ||
1550 | adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz); | ||
1551 | |||
1552 | /* | ||
1553 | * reconfigure the adapter memory to better suit our purposes | ||
1554 | */ | ||
1555 | adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY; | ||
1556 | adapter->tx_pcb.length = 12; | ||
1557 | adapter->tx_pcb.data.memconf.cmd_q = 8; | ||
1558 | adapter->tx_pcb.data.memconf.rcv_q = 8; | ||
1559 | adapter->tx_pcb.data.memconf.mcast = 10; | ||
1560 | adapter->tx_pcb.data.memconf.frame = 10; | ||
1561 | adapter->tx_pcb.data.memconf.rcv_b = 10; | ||
1562 | adapter->tx_pcb.data.memconf.progs = 0; | ||
1563 | if (!send_pcb(dev, &adapter->tx_pcb) || | ||
1564 | !receive_pcb(dev, &adapter->rx_pcb) || | ||
1565 | (adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) || | ||
1566 | (adapter->rx_pcb.length != 2)) { | ||
1567 | pr_err("%s: could not configure adapter memory\n", dev->name); | ||
1568 | } | ||
1569 | if (adapter->rx_pcb.data.configure) { | ||
1570 | pr_err("%s: adapter configuration failed\n", dev->name); | ||
1571 | } | ||
1572 | |||
1573 | dev->netdev_ops = &elp_netdev_ops; | ||
1574 | dev->watchdog_timeo = 10*HZ; | ||
1575 | dev->ethtool_ops = &netdev_ethtool_ops; /* local */ | ||
1576 | |||
1577 | dev->mem_start = dev->mem_end = 0; | ||
1578 | |||
1579 | err = register_netdev(dev); | ||
1580 | if (err) | ||
1581 | goto out; | ||
1582 | |||
1583 | return 0; | ||
1584 | out: | ||
1585 | release_region(dev->base_addr, ELP_IO_EXTENT); | ||
1586 | return err; | ||
1587 | } | ||
1588 | |||
1589 | #ifndef MODULE | ||
1590 | struct net_device * __init elplus_probe(int unit) | ||
1591 | { | ||
1592 | struct net_device *dev = alloc_etherdev(sizeof(elp_device)); | ||
1593 | int err; | ||
1594 | if (!dev) | ||
1595 | return ERR_PTR(-ENOMEM); | ||
1596 | |||
1597 | sprintf(dev->name, "eth%d", unit); | ||
1598 | netdev_boot_setup_check(dev); | ||
1599 | |||
1600 | err = elplus_setup(dev); | ||
1601 | if (err) { | ||
1602 | free_netdev(dev); | ||
1603 | return ERR_PTR(err); | ||
1604 | } | ||
1605 | return dev; | ||
1606 | } | ||
1607 | |||
1608 | #else | ||
1609 | static struct net_device *dev_3c505[ELP_MAX_CARDS]; | ||
1610 | static int io[ELP_MAX_CARDS]; | ||
1611 | static int irq[ELP_MAX_CARDS]; | ||
1612 | static int dma[ELP_MAX_CARDS]; | ||
1613 | module_param_array(io, int, NULL, 0); | ||
1614 | module_param_array(irq, int, NULL, 0); | ||
1615 | module_param_array(dma, int, NULL, 0); | ||
1616 | MODULE_PARM_DESC(io, "EtherLink Plus I/O base address(es)"); | ||
1617 | MODULE_PARM_DESC(irq, "EtherLink Plus IRQ number(s) (assigned)"); | ||
1618 | MODULE_PARM_DESC(dma, "EtherLink Plus DMA channel(s)"); | ||
1619 | |||
1620 | int __init init_module(void) | ||
1621 | { | ||
1622 | int this_dev, found = 0; | ||
1623 | |||
1624 | for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) { | ||
1625 | struct net_device *dev = alloc_etherdev(sizeof(elp_device)); | ||
1626 | if (!dev) | ||
1627 | break; | ||
1628 | |||
1629 | dev->irq = irq[this_dev]; | ||
1630 | dev->base_addr = io[this_dev]; | ||
1631 | if (dma[this_dev]) { | ||
1632 | dev->dma = dma[this_dev]; | ||
1633 | } else { | ||
1634 | dev->dma = ELP_DMA; | ||
1635 | pr_warning("3c505.c: warning, using default DMA channel,\n"); | ||
1636 | } | ||
1637 | if (io[this_dev] == 0) { | ||
1638 | if (this_dev) { | ||
1639 | free_netdev(dev); | ||
1640 | break; | ||
1641 | } | ||
1642 | pr_notice("3c505.c: module autoprobe not recommended, give io=xx.\n"); | ||
1643 | } | ||
1644 | if (elplus_setup(dev) != 0) { | ||
1645 | pr_warning("3c505.c: Failed to register card at 0x%x.\n", io[this_dev]); | ||
1646 | free_netdev(dev); | ||
1647 | break; | ||
1648 | } | ||
1649 | dev_3c505[this_dev] = dev; | ||
1650 | found++; | ||
1651 | } | ||
1652 | if (!found) | ||
1653 | return -ENODEV; | ||
1654 | return 0; | ||
1655 | } | ||
1656 | |||
1657 | void __exit cleanup_module(void) | ||
1658 | { | ||
1659 | int this_dev; | ||
1660 | |||
1661 | for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) { | ||
1662 | struct net_device *dev = dev_3c505[this_dev]; | ||
1663 | if (dev) { | ||
1664 | unregister_netdev(dev); | ||
1665 | release_region(dev->base_addr, ELP_IO_EXTENT); | ||
1666 | free_netdev(dev); | ||
1667 | } | ||
1668 | } | ||
1669 | } | ||
1670 | |||
1671 | #endif /* MODULE */ | ||
1672 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/ethernet/i825xx/3c505.h b/drivers/net/ethernet/i825xx/3c505.h deleted file mode 100644 index 04df2a9002b6..000000000000 --- a/drivers/net/ethernet/i825xx/3c505.h +++ /dev/null | |||
@@ -1,292 +0,0 @@ | |||
1 | /***************************************************************** | ||
2 | * | ||
3 | * defines for 3Com Etherlink Plus adapter | ||
4 | * | ||
5 | *****************************************************************/ | ||
6 | |||
7 | #define ELP_DMA 6 | ||
8 | #define ELP_RX_PCBS 4 | ||
9 | #define ELP_MAX_CARDS 4 | ||
10 | |||
11 | /* | ||
12 | * I/O register offsets | ||
13 | */ | ||
14 | #define PORT_COMMAND 0x00 /* read/write, 8-bit */ | ||
15 | #define PORT_STATUS 0x02 /* read only, 8-bit */ | ||
16 | #define PORT_AUXDMA 0x02 /* write only, 8-bit */ | ||
17 | #define PORT_DATA 0x04 /* read/write, 16-bit */ | ||
18 | #define PORT_CONTROL 0x06 /* read/write, 8-bit */ | ||
19 | |||
20 | #define ELP_IO_EXTENT 0x10 /* size of used IO registers */ | ||
21 | |||
22 | /* | ||
23 | * host control registers bits | ||
24 | */ | ||
25 | #define ATTN 0x80 /* attention */ | ||
26 | #define FLSH 0x40 /* flush data register */ | ||
27 | #define DMAE 0x20 /* DMA enable */ | ||
28 | #define DIR 0x10 /* direction */ | ||
29 | #define TCEN 0x08 /* terminal count interrupt enable */ | ||
30 | #define CMDE 0x04 /* command register interrupt enable */ | ||
31 | #define HSF2 0x02 /* host status flag 2 */ | ||
32 | #define HSF1 0x01 /* host status flag 1 */ | ||
33 | |||
34 | /* | ||
35 | * combinations of HSF flags used for PCB transmission | ||
36 | */ | ||
37 | #define HSF_PCB_ACK HSF1 | ||
38 | #define HSF_PCB_NAK HSF2 | ||
39 | #define HSF_PCB_END (HSF2|HSF1) | ||
40 | #define HSF_PCB_MASK (HSF2|HSF1) | ||
41 | |||
42 | /* | ||
43 | * host status register bits | ||
44 | */ | ||
45 | #define HRDY 0x80 /* data register ready */ | ||
46 | #define HCRE 0x40 /* command register empty */ | ||
47 | #define ACRF 0x20 /* adapter command register full */ | ||
48 | /* #define DIR 0x10 direction - same as in control register */ | ||
49 | #define DONE 0x08 /* DMA done */ | ||
50 | #define ASF3 0x04 /* adapter status flag 3 */ | ||
51 | #define ASF2 0x02 /* adapter status flag 2 */ | ||
52 | #define ASF1 0x01 /* adapter status flag 1 */ | ||
53 | |||
54 | /* | ||
55 | * combinations of ASF flags used for PCB reception | ||
56 | */ | ||
57 | #define ASF_PCB_ACK ASF1 | ||
58 | #define ASF_PCB_NAK ASF2 | ||
59 | #define ASF_PCB_END (ASF2|ASF1) | ||
60 | #define ASF_PCB_MASK (ASF2|ASF1) | ||
61 | |||
62 | /* | ||
63 | * host aux DMA register bits | ||
64 | */ | ||
65 | #define DMA_BRST 0x01 /* DMA burst */ | ||
66 | |||
67 | /* | ||
68 | * maximum amount of data allowed in a PCB | ||
69 | */ | ||
70 | #define MAX_PCB_DATA 62 | ||
71 | |||
72 | /***************************************************************** | ||
73 | * | ||
74 | * timeout value | ||
75 | * this is a rough value used for loops to stop them from | ||
76 | * locking up the whole machine in the case of failure or | ||
77 | * error conditions | ||
78 | * | ||
79 | *****************************************************************/ | ||
80 | |||
81 | #define TIMEOUT 300 | ||
82 | |||
83 | /***************************************************************** | ||
84 | * | ||
85 | * PCB commands | ||
86 | * | ||
87 | *****************************************************************/ | ||
88 | |||
89 | enum { | ||
90 | /* | ||
91 | * host PCB commands | ||
92 | */ | ||
93 | CMD_CONFIGURE_ADAPTER_MEMORY = 0x01, | ||
94 | CMD_CONFIGURE_82586 = 0x02, | ||
95 | CMD_STATION_ADDRESS = 0x03, | ||
96 | CMD_DMA_DOWNLOAD = 0x04, | ||
97 | CMD_DMA_UPLOAD = 0x05, | ||
98 | CMD_PIO_DOWNLOAD = 0x06, | ||
99 | CMD_PIO_UPLOAD = 0x07, | ||
100 | CMD_RECEIVE_PACKET = 0x08, | ||
101 | CMD_TRANSMIT_PACKET = 0x09, | ||
102 | CMD_NETWORK_STATISTICS = 0x0a, | ||
103 | CMD_LOAD_MULTICAST_LIST = 0x0b, | ||
104 | CMD_CLEAR_PROGRAM = 0x0c, | ||
105 | CMD_DOWNLOAD_PROGRAM = 0x0d, | ||
106 | CMD_EXECUTE_PROGRAM = 0x0e, | ||
107 | CMD_SELF_TEST = 0x0f, | ||
108 | CMD_SET_STATION_ADDRESS = 0x10, | ||
109 | CMD_ADAPTER_INFO = 0x11, | ||
110 | NUM_TRANSMIT_CMDS, | ||
111 | |||
112 | /* | ||
113 | * adapter PCB commands | ||
114 | */ | ||
115 | CMD_CONFIGURE_ADAPTER_RESPONSE = 0x31, | ||
116 | CMD_CONFIGURE_82586_RESPONSE = 0x32, | ||
117 | CMD_ADDRESS_RESPONSE = 0x33, | ||
118 | CMD_DOWNLOAD_DATA_REQUEST = 0x34, | ||
119 | CMD_UPLOAD_DATA_REQUEST = 0x35, | ||
120 | CMD_RECEIVE_PACKET_COMPLETE = 0x38, | ||
121 | CMD_TRANSMIT_PACKET_COMPLETE = 0x39, | ||
122 | CMD_NETWORK_STATISTICS_RESPONSE = 0x3a, | ||
123 | CMD_LOAD_MULTICAST_RESPONSE = 0x3b, | ||
124 | CMD_CLEAR_PROGRAM_RESPONSE = 0x3c, | ||
125 | CMD_DOWNLOAD_PROGRAM_RESPONSE = 0x3d, | ||
126 | CMD_EXECUTE_RESPONSE = 0x3e, | ||
127 | CMD_SELF_TEST_RESPONSE = 0x3f, | ||
128 | CMD_SET_ADDRESS_RESPONSE = 0x40, | ||
129 | CMD_ADAPTER_INFO_RESPONSE = 0x41 | ||
130 | }; | ||
131 | |||
132 | /* Definitions for the PCB data structure */ | ||
133 | |||
134 | /* Data units */ | ||
135 | typedef unsigned char byte; | ||
136 | typedef unsigned short int word; | ||
137 | typedef unsigned long int dword; | ||
138 | |||
139 | /* Data structures */ | ||
140 | struct Memconf { | ||
141 | word cmd_q, | ||
142 | rcv_q, | ||
143 | mcast, | ||
144 | frame, | ||
145 | rcv_b, | ||
146 | progs; | ||
147 | }; | ||
148 | |||
149 | struct Rcv_pkt { | ||
150 | word buf_ofs, | ||
151 | buf_seg, | ||
152 | buf_len, | ||
153 | timeout; | ||
154 | }; | ||
155 | |||
156 | struct Xmit_pkt { | ||
157 | word buf_ofs, | ||
158 | buf_seg, | ||
159 | pkt_len; | ||
160 | }; | ||
161 | |||
162 | struct Rcv_resp { | ||
163 | word buf_ofs, | ||
164 | buf_seg, | ||
165 | buf_len, | ||
166 | pkt_len, | ||
167 | timeout, | ||
168 | status; | ||
169 | dword timetag; | ||
170 | }; | ||
171 | |||
172 | struct Xmit_resp { | ||
173 | word buf_ofs, | ||
174 | buf_seg, | ||
175 | c_stat, | ||
176 | status; | ||
177 | }; | ||
178 | |||
179 | |||
180 | struct Netstat { | ||
181 | dword tot_recv, | ||
182 | tot_xmit; | ||
183 | word err_CRC, | ||
184 | err_align, | ||
185 | err_res, | ||
186 | err_ovrrun; | ||
187 | }; | ||
188 | |||
189 | |||
190 | struct Selftest { | ||
191 | word error; | ||
192 | union { | ||
193 | word ROM_cksum; | ||
194 | struct { | ||
195 | word ofs, seg; | ||
196 | } RAM; | ||
197 | word i82586; | ||
198 | } failure; | ||
199 | }; | ||
200 | |||
201 | struct Info { | ||
202 | byte minor_vers, | ||
203 | major_vers; | ||
204 | word ROM_cksum, | ||
205 | RAM_sz, | ||
206 | free_ofs, | ||
207 | free_seg; | ||
208 | }; | ||
209 | |||
210 | struct Memdump { | ||
211 | word size, | ||
212 | off, | ||
213 | seg; | ||
214 | }; | ||
215 | |||
216 | /* | ||
217 | Primary Command Block. The most important data structure. All communication | ||
218 | between the host and the adapter is done with these. (Except for the actual | ||
219 | Ethernet data, which has different packaging.) | ||
220 | */ | ||
221 | typedef struct { | ||
222 | byte command; | ||
223 | byte length; | ||
224 | union { | ||
225 | struct Memconf memconf; | ||
226 | word configure; | ||
227 | struct Rcv_pkt rcv_pkt; | ||
228 | struct Xmit_pkt xmit_pkt; | ||
229 | byte multicast[10][6]; | ||
230 | byte eth_addr[6]; | ||
231 | byte failed; | ||
232 | struct Rcv_resp rcv_resp; | ||
233 | struct Xmit_resp xmit_resp; | ||
234 | struct Netstat netstat; | ||
235 | struct Selftest selftest; | ||
236 | struct Info info; | ||
237 | struct Memdump memdump; | ||
238 | byte raw[62]; | ||
239 | } data; | ||
240 | } pcb_struct; | ||
241 | |||
242 | /* These defines for 'configure' */ | ||
243 | #define RECV_STATION 0x00 | ||
244 | #define RECV_BROAD 0x01 | ||
245 | #define RECV_MULTI 0x02 | ||
246 | #define RECV_PROMISC 0x04 | ||
247 | #define NO_LOOPBACK 0x00 | ||
248 | #define INT_LOOPBACK 0x08 | ||
249 | #define EXT_LOOPBACK 0x10 | ||
250 | |||
251 | /***************************************************************** | ||
252 | * | ||
253 | * structure to hold context information for adapter | ||
254 | * | ||
255 | *****************************************************************/ | ||
256 | |||
257 | #define DMA_BUFFER_SIZE 1600 | ||
258 | #define BACKLOG_SIZE 4 | ||
259 | |||
260 | typedef struct { | ||
261 | volatile short got[NUM_TRANSMIT_CMDS]; /* flags for | ||
262 | command completion */ | ||
263 | pcb_struct tx_pcb; /* PCB for foreground sending */ | ||
264 | pcb_struct rx_pcb; /* PCB for foreground receiving */ | ||
265 | pcb_struct itx_pcb; /* PCB for background sending */ | ||
266 | pcb_struct irx_pcb; /* PCB for background receiving */ | ||
267 | |||
268 | void *dma_buffer; | ||
269 | |||
270 | struct { | ||
271 | unsigned int length[BACKLOG_SIZE]; | ||
272 | unsigned int in; | ||
273 | unsigned int out; | ||
274 | } rx_backlog; | ||
275 | |||
276 | struct { | ||
277 | unsigned int direction; | ||
278 | unsigned int length; | ||
279 | struct sk_buff *skb; | ||
280 | void *target; | ||
281 | unsigned long start_time; | ||
282 | } current_dma; | ||
283 | |||
284 | /* flags */ | ||
285 | unsigned long send_pcb_semaphore; | ||
286 | unsigned long dmaing; | ||
287 | unsigned long busy; | ||
288 | |||
289 | unsigned int rx_active; /* number of receive PCBs */ | ||
290 | volatile unsigned char hcr_val; /* what we think the HCR contains */ | ||
291 | spinlock_t lock; /* Interrupt v tx lock */ | ||
292 | } elp_device; | ||
diff --git a/drivers/net/ethernet/i825xx/3c507.c b/drivers/net/ethernet/i825xx/3c507.c deleted file mode 100644 index 13983ee6bcf8..000000000000 --- a/drivers/net/ethernet/i825xx/3c507.c +++ /dev/null | |||
@@ -1,939 +0,0 @@ | |||
1 | /* 3c507.c: An EtherLink16 device driver for Linux. */ | ||
2 | /* | ||
3 | Written 1993,1994 by Donald Becker. | ||
4 | |||
5 | Copyright 1993 United States Government as represented by the | ||
6 | Director, National Security Agency. | ||
7 | |||
8 | This software may be used and distributed according to the terms | ||
9 | of the GNU General Public License, incorporated herein by reference. | ||
10 | |||
11 | The author may be reached as becker@scyld.com, or C/O | ||
12 | Scyld Computing Corporation | ||
13 | 410 Severn Ave., Suite 210 | ||
14 | Annapolis MD 21403 | ||
15 | |||
16 | |||
17 | Thanks go to jennings@Montrouge.SMR.slb.com ( Patrick Jennings) | ||
18 | and jrs@world.std.com (Rick Sladkey) for testing and bugfixes. | ||
19 | Mark Salazar <leslie@access.digex.net> made the changes for cards with | ||
20 | only 16K packet buffers. | ||
21 | |||
22 | Things remaining to do: | ||
23 | Verify that the tx and rx buffers don't have fencepost errors. | ||
24 | Move the theory of operation and memory map documentation. | ||
25 | The statistics need to be updated correctly. | ||
26 | */ | ||
27 | |||
28 | #define DRV_NAME "3c507" | ||
29 | #define DRV_VERSION "1.10a" | ||
30 | #define DRV_RELDATE "11/17/2001" | ||
31 | |||
32 | static const char version[] = | ||
33 | DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Donald Becker (becker@scyld.com)\n"; | ||
34 | |||
35 | /* | ||
36 | Sources: | ||
37 | This driver wouldn't have been written with the availability of the | ||
38 | Crynwr driver source code. It provided a known-working implementation | ||
39 | that filled in the gaping holes of the Intel documentation. Three cheers | ||
40 | for Russ Nelson. | ||
41 | |||
42 | Intel Microcommunications Databook, Vol. 1, 1990. It provides just enough | ||
43 | info that the casual reader might think that it documents the i82586 :-<. | ||
44 | */ | ||
45 | |||
46 | #include <linux/module.h> | ||
47 | #include <linux/kernel.h> | ||
48 | #include <linux/types.h> | ||
49 | #include <linux/fcntl.h> | ||
50 | #include <linux/interrupt.h> | ||
51 | #include <linux/ioport.h> | ||
52 | #include <linux/in.h> | ||
53 | #include <linux/string.h> | ||
54 | #include <linux/spinlock.h> | ||
55 | #include <linux/ethtool.h> | ||
56 | #include <linux/errno.h> | ||
57 | #include <linux/netdevice.h> | ||
58 | #include <linux/etherdevice.h> | ||
59 | #include <linux/if_ether.h> | ||
60 | #include <linux/skbuff.h> | ||
61 | #include <linux/init.h> | ||
62 | #include <linux/bitops.h> | ||
63 | |||
64 | #include <asm/dma.h> | ||
65 | #include <asm/io.h> | ||
66 | #include <asm/uaccess.h> | ||
67 | |||
68 | /* use 0 for production, 1 for verification, 2..7 for debug */ | ||
69 | #ifndef NET_DEBUG | ||
70 | #define NET_DEBUG 1 | ||
71 | #endif | ||
72 | static unsigned int net_debug = NET_DEBUG; | ||
73 | #define debug net_debug | ||
74 | |||
75 | |||
76 | /* | ||
77 | Details of the i82586. | ||
78 | |||
79 | You'll really need the databook to understand the details of this part, | ||
80 | but the outline is that the i82586 has two separate processing units. | ||
81 | Both are started from a list of three configuration tables, of which only | ||
82 | the last, the System Control Block (SCB), is used after reset-time. The SCB | ||
83 | has the following fields: | ||
84 | Status word | ||
85 | Command word | ||
86 | Tx/Command block addr. | ||
87 | Rx block addr. | ||
88 | The command word accepts the following controls for the Tx and Rx units: | ||
89 | */ | ||
90 | |||
91 | #define CUC_START 0x0100 | ||
92 | #define CUC_RESUME 0x0200 | ||
93 | #define CUC_SUSPEND 0x0300 | ||
94 | #define RX_START 0x0010 | ||
95 | #define RX_RESUME 0x0020 | ||
96 | #define RX_SUSPEND 0x0030 | ||
97 | |||
98 | /* The Rx unit uses a list of frame descriptors and a list of data buffer | ||
99 | descriptors. We use full-sized (1518 byte) data buffers, so there is | ||
100 | a one-to-one pairing of frame descriptors to buffer descriptors. | ||
101 | |||
102 | The Tx ("command") unit executes a list of commands that look like: | ||
103 | Status word Written by the 82586 when the command is done. | ||
104 | Command word Command in lower 3 bits, post-command action in upper 3 | ||
105 | Link word The address of the next command. | ||
106 | Parameters (as needed). | ||
107 | |||
108 | Some definitions related to the Command Word are: | ||
109 | */ | ||
110 | #define CMD_EOL 0x8000 /* The last command of the list, stop. */ | ||
111 | #define CMD_SUSP 0x4000 /* Suspend after doing cmd. */ | ||
112 | #define CMD_INTR 0x2000 /* Interrupt after doing cmd. */ | ||
113 | |||
114 | enum commands { | ||
115 | CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3, | ||
116 | CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7}; | ||
117 | |||
118 | /* Information that need to be kept for each board. */ | ||
119 | struct net_local { | ||
120 | int last_restart; | ||
121 | ushort rx_head; | ||
122 | ushort rx_tail; | ||
123 | ushort tx_head; | ||
124 | ushort tx_cmd_link; | ||
125 | ushort tx_reap; | ||
126 | ushort tx_pkts_in_ring; | ||
127 | spinlock_t lock; | ||
128 | void __iomem *base; | ||
129 | }; | ||
130 | |||
131 | /* | ||
132 | Details of the EtherLink16 Implementation | ||
133 | The 3c507 is a generic shared-memory i82586 implementation. | ||
134 | The host can map 16K, 32K, 48K, or 64K of the 64K memory into | ||
135 | 0x0[CD][08]0000, or all 64K into 0xF[02468]0000. | ||
136 | */ | ||
137 | |||
138 | /* Offsets from the base I/O address. */ | ||
139 | #define SA_DATA 0 /* Station address data, or 3Com signature. */ | ||
140 | #define MISC_CTRL 6 /* Switch the SA_DATA banks, and bus config bits. */ | ||
141 | #define RESET_IRQ 10 /* Reset the latched IRQ line. */ | ||
142 | #define SIGNAL_CA 11 /* Frob the 82586 Channel Attention line. */ | ||
143 | #define ROM_CONFIG 13 | ||
144 | #define MEM_CONFIG 14 | ||
145 | #define IRQ_CONFIG 15 | ||
146 | #define EL16_IO_EXTENT 16 | ||
147 | |||
148 | /* The ID port is used at boot-time to locate the ethercard. */ | ||
149 | #define ID_PORT 0x100 | ||
150 | |||
151 | /* Offsets to registers in the mailbox (SCB). */ | ||
152 | #define iSCB_STATUS 0x8 | ||
153 | #define iSCB_CMD 0xA | ||
154 | #define iSCB_CBL 0xC /* Command BLock offset. */ | ||
155 | #define iSCB_RFA 0xE /* Rx Frame Area offset. */ | ||
156 | |||
157 | /* Since the 3c507 maps the shared memory window so that the last byte is | ||
158 | at 82586 address FFFF, the first byte is at 82586 address 0, 16K, 32K, or | ||
159 | 48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively. | ||
160 | We can account for this be setting the 'SBC Base' entry in the ISCP table | ||
161 | below for all the 16 bit offset addresses, and also adding the 'SCB Base' | ||
162 | value to all 24 bit physical addresses (in the SCP table and the TX and RX | ||
163 | Buffer Descriptors). | ||
164 | -Mark | ||
165 | */ | ||
166 | #define SCB_BASE ((unsigned)64*1024 - (dev->mem_end - dev->mem_start)) | ||
167 | |||
168 | /* | ||
169 | What follows in 'init_words[]' is the "program" that is downloaded to the | ||
170 | 82586 memory. It's mostly tables and command blocks, and starts at the | ||
171 | reset address 0xfffff6. This is designed to be similar to the EtherExpress, | ||
172 | thus the unusual location of the SCB at 0x0008. | ||
173 | |||
174 | Even with the additional "don't care" values, doing it this way takes less | ||
175 | program space than initializing the individual tables, and I feel it's much | ||
176 | cleaner. | ||
177 | |||
178 | The databook is particularly useless for the first two structures, I had | ||
179 | to use the Crynwr driver as an example. | ||
180 | |||
181 | The memory setup is as follows: | ||
182 | */ | ||
183 | |||
184 | #define CONFIG_CMD 0x0018 | ||
185 | #define SET_SA_CMD 0x0024 | ||
186 | #define SA_OFFSET 0x002A | ||
187 | #define IDLELOOP 0x30 | ||
188 | #define TDR_CMD 0x38 | ||
189 | #define TDR_TIME 0x3C | ||
190 | #define DUMP_CMD 0x40 | ||
191 | #define DIAG_CMD 0x48 | ||
192 | #define SET_MC_CMD 0x4E | ||
193 | #define DUMP_DATA 0x56 /* A 170 byte buffer for dump and Set-MC into. */ | ||
194 | |||
195 | #define TX_BUF_START 0x0100 | ||
196 | #define NUM_TX_BUFS 5 | ||
197 | #define TX_BUF_SIZE (1518+14+20+16) /* packet+header+TBD */ | ||
198 | |||
199 | #define RX_BUF_START 0x2000 | ||
200 | #define RX_BUF_SIZE (1518+14+18) /* packet+header+RBD */ | ||
201 | #define RX_BUF_END (dev->mem_end - dev->mem_start) | ||
202 | |||
203 | #define TX_TIMEOUT (HZ/20) | ||
204 | |||
205 | /* | ||
206 | That's it: only 86 bytes to set up the beast, including every extra | ||
207 | command available. The 170 byte buffer at DUMP_DATA is shared between the | ||
208 | Dump command (called only by the diagnostic program) and the SetMulticastList | ||
209 | command. | ||
210 | |||
211 | To complete the memory setup you only have to write the station address at | ||
212 | SA_OFFSET and create the Tx & Rx buffer lists. | ||
213 | |||
214 | The Tx command chain and buffer list is setup as follows: | ||
215 | A Tx command table, with the data buffer pointing to... | ||
216 | A Tx data buffer descriptor. The packet is in a single buffer, rather than | ||
217 | chaining together several smaller buffers. | ||
218 | A NoOp command, which initially points to itself, | ||
219 | And the packet data. | ||
220 | |||
221 | A transmit is done by filling in the Tx command table and data buffer, | ||
222 | re-writing the NoOp command, and finally changing the offset of the last | ||
223 | command to point to the current Tx command. When the Tx command is finished, | ||
224 | it jumps to the NoOp, when it loops until the next Tx command changes the | ||
225 | "link offset" in the NoOp. This way the 82586 never has to go through the | ||
226 | slow restart sequence. | ||
227 | |||
228 | The Rx buffer list is set up in the obvious ring structure. We have enough | ||
229 | memory (and low enough interrupt latency) that we can avoid the complicated | ||
230 | Rx buffer linked lists by alway associating a full-size Rx data buffer with | ||
231 | each Rx data frame. | ||
232 | |||
233 | I current use four transmit buffers starting at TX_BUF_START (0x0100), and | ||
234 | use the rest of memory, from RX_BUF_START to RX_BUF_END, for Rx buffers. | ||
235 | |||
236 | */ | ||
237 | |||
238 | static unsigned short init_words[] = { | ||
239 | /* System Configuration Pointer (SCP). */ | ||
240 | 0x0000, /* Set bus size to 16 bits. */ | ||
241 | 0,0, /* pad words. */ | ||
242 | 0x0000,0x0000, /* ISCP phys addr, set in init_82586_mem(). */ | ||
243 | |||
244 | /* Intermediate System Configuration Pointer (ISCP). */ | ||
245 | 0x0001, /* Status word that's cleared when init is done. */ | ||
246 | 0x0008,0,0, /* SCB offset, (skip, skip) */ | ||
247 | |||
248 | /* System Control Block (SCB). */ | ||
249 | 0,0xf000|RX_START|CUC_START, /* SCB status and cmd. */ | ||
250 | CONFIG_CMD, /* Command list pointer, points to Configure. */ | ||
251 | RX_BUF_START, /* Rx block list. */ | ||
252 | 0,0,0,0, /* Error count: CRC, align, buffer, overrun. */ | ||
253 | |||
254 | /* 0x0018: Configure command. Change to put MAC data with packet. */ | ||
255 | 0, CmdConfigure, /* Status, command. */ | ||
256 | SET_SA_CMD, /* Next command is Set Station Addr. */ | ||
257 | 0x0804, /* "4" bytes of config data, 8 byte FIFO. */ | ||
258 | 0x2e40, /* Magic values, including MAC data location. */ | ||
259 | 0, /* Unused pad word. */ | ||
260 | |||
261 | /* 0x0024: Setup station address command. */ | ||
262 | 0, CmdSASetup, | ||
263 | SET_MC_CMD, /* Next command. */ | ||
264 | 0xaa00,0xb000,0x0bad, /* Station address (to be filled in) */ | ||
265 | |||
266 | /* 0x0030: NOP, looping back to itself. Point to first Tx buffer to Tx. */ | ||
267 | 0, CmdNOp, IDLELOOP, 0 /* pad */, | ||
268 | |||
269 | /* 0x0038: A unused Time-Domain Reflectometer command. */ | ||
270 | 0, CmdTDR, IDLELOOP, 0, | ||
271 | |||
272 | /* 0x0040: An unused Dump State command. */ | ||
273 | 0, CmdDump, IDLELOOP, DUMP_DATA, | ||
274 | |||
275 | /* 0x0048: An unused Diagnose command. */ | ||
276 | 0, CmdDiagnose, IDLELOOP, | ||
277 | |||
278 | /* 0x004E: An empty set-multicast-list command. */ | ||
279 | 0, CmdMulticastList, IDLELOOP, 0, | ||
280 | }; | ||
281 | |||
282 | /* Index to functions, as function prototypes. */ | ||
283 | |||
284 | static int el16_probe1(struct net_device *dev, int ioaddr); | ||
285 | static int el16_open(struct net_device *dev); | ||
286 | static netdev_tx_t el16_send_packet(struct sk_buff *skb, | ||
287 | struct net_device *dev); | ||
288 | static irqreturn_t el16_interrupt(int irq, void *dev_id); | ||
289 | static void el16_rx(struct net_device *dev); | ||
290 | static int el16_close(struct net_device *dev); | ||
291 | static void el16_tx_timeout (struct net_device *dev); | ||
292 | |||
293 | static void hardware_send_packet(struct net_device *dev, void *buf, short length, short pad); | ||
294 | static void init_82586_mem(struct net_device *dev); | ||
295 | static const struct ethtool_ops netdev_ethtool_ops; | ||
296 | static void init_rx_bufs(struct net_device *); | ||
297 | |||
298 | static int io = 0x300; | ||
299 | static int irq; | ||
300 | static int mem_start; | ||
301 | |||
302 | |||
303 | /* Check for a network adaptor of this type, and return '0' iff one exists. | ||
304 | If dev->base_addr == 0, probe all likely locations. | ||
305 | If dev->base_addr == 1, always return failure. | ||
306 | If dev->base_addr == 2, (detachable devices only) allocate space for the | ||
307 | device and return success. | ||
308 | */ | ||
309 | |||
310 | struct net_device * __init el16_probe(int unit) | ||
311 | { | ||
312 | struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); | ||
313 | static const unsigned ports[] = { 0x300, 0x320, 0x340, 0x280, 0}; | ||
314 | const unsigned *port; | ||
315 | int err = -ENODEV; | ||
316 | |||
317 | if (!dev) | ||
318 | return ERR_PTR(-ENODEV); | ||
319 | |||
320 | if (unit >= 0) { | ||
321 | sprintf(dev->name, "eth%d", unit); | ||
322 | netdev_boot_setup_check(dev); | ||
323 | io = dev->base_addr; | ||
324 | irq = dev->irq; | ||
325 | mem_start = dev->mem_start & 15; | ||
326 | } | ||
327 | |||
328 | if (io > 0x1ff) /* Check a single specified location. */ | ||
329 | err = el16_probe1(dev, io); | ||
330 | else if (io != 0) | ||
331 | err = -ENXIO; /* Don't probe at all. */ | ||
332 | else { | ||
333 | for (port = ports; *port; port++) { | ||
334 | err = el16_probe1(dev, *port); | ||
335 | if (!err) | ||
336 | break; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | if (err) | ||
341 | goto out; | ||
342 | err = register_netdev(dev); | ||
343 | if (err) | ||
344 | goto out1; | ||
345 | return dev; | ||
346 | out1: | ||
347 | free_irq(dev->irq, dev); | ||
348 | iounmap(((struct net_local *)netdev_priv(dev))->base); | ||
349 | release_region(dev->base_addr, EL16_IO_EXTENT); | ||
350 | out: | ||
351 | free_netdev(dev); | ||
352 | return ERR_PTR(err); | ||
353 | } | ||
354 | |||
355 | static const struct net_device_ops netdev_ops = { | ||
356 | .ndo_open = el16_open, | ||
357 | .ndo_stop = el16_close, | ||
358 | .ndo_start_xmit = el16_send_packet, | ||
359 | .ndo_tx_timeout = el16_tx_timeout, | ||
360 | .ndo_change_mtu = eth_change_mtu, | ||
361 | .ndo_set_mac_address = eth_mac_addr, | ||
362 | .ndo_validate_addr = eth_validate_addr, | ||
363 | }; | ||
364 | |||
365 | static int __init el16_probe1(struct net_device *dev, int ioaddr) | ||
366 | { | ||
367 | static unsigned char init_ID_done; | ||
368 | int i, irq, irqval, retval; | ||
369 | struct net_local *lp; | ||
370 | |||
371 | if (init_ID_done == 0) { | ||
372 | ushort lrs_state = 0xff; | ||
373 | /* Send the ID sequence to the ID_PORT to enable the board(s). */ | ||
374 | outb(0x00, ID_PORT); | ||
375 | for(i = 0; i < 255; i++) { | ||
376 | outb(lrs_state, ID_PORT); | ||
377 | lrs_state <<= 1; | ||
378 | if (lrs_state & 0x100) | ||
379 | lrs_state ^= 0xe7; | ||
380 | } | ||
381 | outb(0x00, ID_PORT); | ||
382 | init_ID_done = 1; | ||
383 | } | ||
384 | |||
385 | if (!request_region(ioaddr, EL16_IO_EXTENT, DRV_NAME)) | ||
386 | return -ENODEV; | ||
387 | |||
388 | if ((inb(ioaddr) != '*') || (inb(ioaddr + 1) != '3') || | ||
389 | (inb(ioaddr + 2) != 'C') || (inb(ioaddr + 3) != 'O')) { | ||
390 | retval = -ENODEV; | ||
391 | goto out; | ||
392 | } | ||
393 | |||
394 | pr_info("%s: 3c507 at %#x,", dev->name, ioaddr); | ||
395 | |||
396 | /* We should make a few more checks here, like the first three octets of | ||
397 | the S.A. for the manufacturer's code. */ | ||
398 | |||
399 | irq = inb(ioaddr + IRQ_CONFIG) & 0x0f; | ||
400 | |||
401 | irqval = request_irq(irq, el16_interrupt, 0, DRV_NAME, dev); | ||
402 | if (irqval) { | ||
403 | pr_cont("\n"); | ||
404 | pr_err("3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval); | ||
405 | retval = -EAGAIN; | ||
406 | goto out; | ||
407 | } | ||
408 | |||
409 | /* We've committed to using the board, and can start filling in *dev. */ | ||
410 | dev->base_addr = ioaddr; | ||
411 | |||
412 | outb(0x01, ioaddr + MISC_CTRL); | ||
413 | for (i = 0; i < 6; i++) | ||
414 | dev->dev_addr[i] = inb(ioaddr + i); | ||
415 | pr_cont(" %pM", dev->dev_addr); | ||
416 | |||
417 | if (mem_start) | ||
418 | net_debug = mem_start & 7; | ||
419 | |||
420 | #ifdef MEM_BASE | ||
421 | dev->mem_start = MEM_BASE; | ||
422 | dev->mem_end = dev->mem_start + 0x10000; | ||
423 | #else | ||
424 | { | ||
425 | int base; | ||
426 | int size; | ||
427 | char mem_config = inb(ioaddr + MEM_CONFIG); | ||
428 | if (mem_config & 0x20) { | ||
429 | size = 64*1024; | ||
430 | base = 0xf00000 + (mem_config & 0x08 ? 0x080000 | ||
431 | : ((mem_config & 3) << 17)); | ||
432 | } else { | ||
433 | size = ((mem_config & 3) + 1) << 14; | ||
434 | base = 0x0c0000 + ( (mem_config & 0x18) << 12); | ||
435 | } | ||
436 | dev->mem_start = base; | ||
437 | dev->mem_end = base + size; | ||
438 | } | ||
439 | #endif | ||
440 | |||
441 | dev->if_port = (inb(ioaddr + ROM_CONFIG) & 0x80) ? 1 : 0; | ||
442 | dev->irq = inb(ioaddr + IRQ_CONFIG) & 0x0f; | ||
443 | |||
444 | pr_cont(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq, | ||
445 | dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1); | ||
446 | |||
447 | if (net_debug) | ||
448 | pr_debug("%s", version); | ||
449 | |||
450 | lp = netdev_priv(dev); | ||
451 | spin_lock_init(&lp->lock); | ||
452 | lp->base = ioremap(dev->mem_start, RX_BUF_END); | ||
453 | if (!lp->base) { | ||
454 | pr_err("3c507: unable to remap memory\n"); | ||
455 | retval = -EAGAIN; | ||
456 | goto out1; | ||
457 | } | ||
458 | |||
459 | dev->netdev_ops = &netdev_ops; | ||
460 | dev->watchdog_timeo = TX_TIMEOUT; | ||
461 | dev->ethtool_ops = &netdev_ethtool_ops; | ||
462 | dev->flags &= ~IFF_MULTICAST; /* Multicast doesn't work */ | ||
463 | return 0; | ||
464 | out1: | ||
465 | free_irq(dev->irq, dev); | ||
466 | out: | ||
467 | release_region(ioaddr, EL16_IO_EXTENT); | ||
468 | return retval; | ||
469 | } | ||
470 | |||
471 | static int el16_open(struct net_device *dev) | ||
472 | { | ||
473 | /* Initialize the 82586 memory and start it. */ | ||
474 | init_82586_mem(dev); | ||
475 | |||
476 | netif_start_queue(dev); | ||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | |||
481 | static void el16_tx_timeout (struct net_device *dev) | ||
482 | { | ||
483 | struct net_local *lp = netdev_priv(dev); | ||
484 | int ioaddr = dev->base_addr; | ||
485 | void __iomem *shmem = lp->base; | ||
486 | |||
487 | if (net_debug > 1) | ||
488 | pr_debug("%s: transmit timed out, %s? ", dev->name, | ||
489 | readw(shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" : | ||
490 | "network cable problem"); | ||
491 | /* Try to restart the adaptor. */ | ||
492 | if (lp->last_restart == dev->stats.tx_packets) { | ||
493 | if (net_debug > 1) | ||
494 | pr_cont("Resetting board.\n"); | ||
495 | /* Completely reset the adaptor. */ | ||
496 | init_82586_mem (dev); | ||
497 | lp->tx_pkts_in_ring = 0; | ||
498 | } else { | ||
499 | /* Issue the channel attention signal and hope it "gets better". */ | ||
500 | if (net_debug > 1) | ||
501 | pr_cont("Kicking board.\n"); | ||
502 | writew(0xf000 | CUC_START | RX_START, shmem + iSCB_CMD); | ||
503 | outb (0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */ | ||
504 | lp->last_restart = dev->stats.tx_packets; | ||
505 | } | ||
506 | dev->trans_start = jiffies; /* prevent tx timeout */ | ||
507 | netif_wake_queue (dev); | ||
508 | } | ||
509 | |||
510 | |||
511 | static netdev_tx_t el16_send_packet (struct sk_buff *skb, | ||
512 | struct net_device *dev) | ||
513 | { | ||
514 | struct net_local *lp = netdev_priv(dev); | ||
515 | int ioaddr = dev->base_addr; | ||
516 | unsigned long flags; | ||
517 | short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; | ||
518 | unsigned char *buf = skb->data; | ||
519 | |||
520 | netif_stop_queue (dev); | ||
521 | |||
522 | spin_lock_irqsave (&lp->lock, flags); | ||
523 | |||
524 | dev->stats.tx_bytes += length; | ||
525 | /* Disable the 82586's input to the interrupt line. */ | ||
526 | outb (0x80, ioaddr + MISC_CTRL); | ||
527 | |||
528 | hardware_send_packet (dev, buf, skb->len, length - skb->len); | ||
529 | |||
530 | /* Enable the 82586 interrupt input. */ | ||
531 | outb (0x84, ioaddr + MISC_CTRL); | ||
532 | |||
533 | spin_unlock_irqrestore (&lp->lock, flags); | ||
534 | |||
535 | dev_kfree_skb (skb); | ||
536 | |||
537 | /* You might need to clean up and record Tx statistics here. */ | ||
538 | |||
539 | return NETDEV_TX_OK; | ||
540 | } | ||
541 | |||
542 | /* The typical workload of the driver: | ||
543 | Handle the network interface interrupts. */ | ||
544 | static irqreturn_t el16_interrupt(int irq, void *dev_id) | ||
545 | { | ||
546 | struct net_device *dev = dev_id; | ||
547 | struct net_local *lp; | ||
548 | int ioaddr, status, boguscount = 0; | ||
549 | ushort ack_cmd = 0; | ||
550 | void __iomem *shmem; | ||
551 | |||
552 | if (dev == NULL) { | ||
553 | pr_err("net_interrupt(): irq %d for unknown device.\n", irq); | ||
554 | return IRQ_NONE; | ||
555 | } | ||
556 | |||
557 | ioaddr = dev->base_addr; | ||
558 | lp = netdev_priv(dev); | ||
559 | shmem = lp->base; | ||
560 | |||
561 | spin_lock(&lp->lock); | ||
562 | |||
563 | status = readw(shmem+iSCB_STATUS); | ||
564 | |||
565 | if (net_debug > 4) { | ||
566 | pr_debug("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status); | ||
567 | } | ||
568 | |||
569 | /* Disable the 82586's input to the interrupt line. */ | ||
570 | outb(0x80, ioaddr + MISC_CTRL); | ||
571 | |||
572 | /* Reap the Tx packet buffers. */ | ||
573 | while (lp->tx_pkts_in_ring) { | ||
574 | unsigned short tx_status = readw(shmem+lp->tx_reap); | ||
575 | if (!(tx_status & 0x8000)) { | ||
576 | if (net_debug > 5) | ||
577 | pr_debug("Tx command incomplete (%#x).\n", lp->tx_reap); | ||
578 | break; | ||
579 | } | ||
580 | /* Tx unsuccessful or some interesting status bit set. */ | ||
581 | if (!(tx_status & 0x2000) || (tx_status & 0x0f3f)) { | ||
582 | dev->stats.tx_errors++; | ||
583 | if (tx_status & 0x0600) dev->stats.tx_carrier_errors++; | ||
584 | if (tx_status & 0x0100) dev->stats.tx_fifo_errors++; | ||
585 | if (!(tx_status & 0x0040)) dev->stats.tx_heartbeat_errors++; | ||
586 | if (tx_status & 0x0020) dev->stats.tx_aborted_errors++; | ||
587 | dev->stats.collisions += tx_status & 0xf; | ||
588 | } | ||
589 | dev->stats.tx_packets++; | ||
590 | if (net_debug > 5) | ||
591 | pr_debug("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status); | ||
592 | lp->tx_reap += TX_BUF_SIZE; | ||
593 | if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE) | ||
594 | lp->tx_reap = TX_BUF_START; | ||
595 | |||
596 | lp->tx_pkts_in_ring--; | ||
597 | /* There is always more space in the Tx ring buffer now. */ | ||
598 | netif_wake_queue(dev); | ||
599 | |||
600 | if (++boguscount > 10) | ||
601 | break; | ||
602 | } | ||
603 | |||
604 | if (status & 0x4000) { /* Packet received. */ | ||
605 | if (net_debug > 5) | ||
606 | pr_debug("Received packet, rx_head %04x.\n", lp->rx_head); | ||
607 | el16_rx(dev); | ||
608 | } | ||
609 | |||
610 | /* Acknowledge the interrupt sources. */ | ||
611 | ack_cmd = status & 0xf000; | ||
612 | |||
613 | if ((status & 0x0700) != 0x0200 && netif_running(dev)) { | ||
614 | if (net_debug) | ||
615 | pr_debug("%s: Command unit stopped, status %04x, restarting.\n", | ||
616 | dev->name, status); | ||
617 | /* If this ever occurs we should really re-write the idle loop, reset | ||
618 | the Tx list, and do a complete restart of the command unit. | ||
619 | For now we rely on the Tx timeout if the resume doesn't work. */ | ||
620 | ack_cmd |= CUC_RESUME; | ||
621 | } | ||
622 | |||
623 | if ((status & 0x0070) != 0x0040 && netif_running(dev)) { | ||
624 | /* The Rx unit is not ready, it must be hung. Restart the receiver by | ||
625 | initializing the rx buffers, and issuing an Rx start command. */ | ||
626 | if (net_debug) | ||
627 | pr_debug("%s: Rx unit stopped, status %04x, restarting.\n", | ||
628 | dev->name, status); | ||
629 | init_rx_bufs(dev); | ||
630 | writew(RX_BUF_START,shmem+iSCB_RFA); | ||
631 | ack_cmd |= RX_START; | ||
632 | } | ||
633 | |||
634 | writew(ack_cmd,shmem+iSCB_CMD); | ||
635 | outb(0, ioaddr + SIGNAL_CA); /* Issue channel-attn. */ | ||
636 | |||
637 | /* Clear the latched interrupt. */ | ||
638 | outb(0, ioaddr + RESET_IRQ); | ||
639 | |||
640 | /* Enable the 82586's interrupt input. */ | ||
641 | outb(0x84, ioaddr + MISC_CTRL); | ||
642 | spin_unlock(&lp->lock); | ||
643 | return IRQ_HANDLED; | ||
644 | } | ||
645 | |||
646 | static int el16_close(struct net_device *dev) | ||
647 | { | ||
648 | struct net_local *lp = netdev_priv(dev); | ||
649 | int ioaddr = dev->base_addr; | ||
650 | void __iomem *shmem = lp->base; | ||
651 | |||
652 | netif_stop_queue(dev); | ||
653 | |||
654 | /* Flush the Tx and disable Rx. */ | ||
655 | writew(RX_SUSPEND | CUC_SUSPEND,shmem+iSCB_CMD); | ||
656 | outb(0, ioaddr + SIGNAL_CA); | ||
657 | |||
658 | /* Disable the 82586's input to the interrupt line. */ | ||
659 | outb(0x80, ioaddr + MISC_CTRL); | ||
660 | |||
661 | /* We always physically use the IRQ line, so we don't do free_irq(). */ | ||
662 | |||
663 | /* Update the statistics here. */ | ||
664 | |||
665 | return 0; | ||
666 | } | ||
667 | |||
668 | /* Initialize the Rx-block list. */ | ||
669 | static void init_rx_bufs(struct net_device *dev) | ||
670 | { | ||
671 | struct net_local *lp = netdev_priv(dev); | ||
672 | void __iomem *write_ptr; | ||
673 | unsigned short SCB_base = SCB_BASE; | ||
674 | |||
675 | int cur_rxbuf = lp->rx_head = RX_BUF_START; | ||
676 | |||
677 | /* Initialize each Rx frame + data buffer. */ | ||
678 | do { /* While there is room for one more. */ | ||
679 | |||
680 | write_ptr = lp->base + cur_rxbuf; | ||
681 | |||
682 | writew(0x0000,write_ptr); /* Status */ | ||
683 | writew(0x0000,write_ptr+=2); /* Command */ | ||
684 | writew(cur_rxbuf + RX_BUF_SIZE,write_ptr+=2); /* Link */ | ||
685 | writew(cur_rxbuf + 22,write_ptr+=2); /* Buffer offset */ | ||
686 | writew(0x0000,write_ptr+=2); /* Pad for dest addr. */ | ||
687 | writew(0x0000,write_ptr+=2); | ||
688 | writew(0x0000,write_ptr+=2); | ||
689 | writew(0x0000,write_ptr+=2); /* Pad for source addr. */ | ||
690 | writew(0x0000,write_ptr+=2); | ||
691 | writew(0x0000,write_ptr+=2); | ||
692 | writew(0x0000,write_ptr+=2); /* Pad for protocol. */ | ||
693 | |||
694 | writew(0x0000,write_ptr+=2); /* Buffer: Actual count */ | ||
695 | writew(-1,write_ptr+=2); /* Buffer: Next (none). */ | ||
696 | writew(cur_rxbuf + 0x20 + SCB_base,write_ptr+=2);/* Buffer: Address low */ | ||
697 | writew(0x0000,write_ptr+=2); | ||
698 | /* Finally, the number of bytes in the buffer. */ | ||
699 | writew(0x8000 + RX_BUF_SIZE-0x20,write_ptr+=2); | ||
700 | |||
701 | lp->rx_tail = cur_rxbuf; | ||
702 | cur_rxbuf += RX_BUF_SIZE; | ||
703 | } while (cur_rxbuf <= RX_BUF_END - RX_BUF_SIZE); | ||
704 | |||
705 | /* Terminate the list by setting the EOL bit, and wrap the pointer to make | ||
706 | the list a ring. */ | ||
707 | write_ptr = lp->base + lp->rx_tail + 2; | ||
708 | writew(0xC000,write_ptr); /* Command, mark as last. */ | ||
709 | writew(lp->rx_head,write_ptr+2); /* Link */ | ||
710 | } | ||
711 | |||
712 | static void init_82586_mem(struct net_device *dev) | ||
713 | { | ||
714 | struct net_local *lp = netdev_priv(dev); | ||
715 | short ioaddr = dev->base_addr; | ||
716 | void __iomem *shmem = lp->base; | ||
717 | |||
718 | /* Enable loopback to protect the wire while starting up, | ||
719 | and hold the 586 in reset during the memory initialization. */ | ||
720 | outb(0x20, ioaddr + MISC_CTRL); | ||
721 | |||
722 | /* Fix the ISCP address and base. */ | ||
723 | init_words[3] = SCB_BASE; | ||
724 | init_words[7] = SCB_BASE; | ||
725 | |||
726 | /* Write the words at 0xfff6 (address-aliased to 0xfffff6). */ | ||
727 | memcpy_toio(lp->base + RX_BUF_END - 10, init_words, 10); | ||
728 | |||
729 | /* Write the words at 0x0000. */ | ||
730 | memcpy_toio(lp->base, init_words + 5, sizeof(init_words) - 10); | ||
731 | |||
732 | /* Fill in the station address. */ | ||
733 | memcpy_toio(lp->base+SA_OFFSET, dev->dev_addr, ETH_ALEN); | ||
734 | |||
735 | /* The Tx-block list is written as needed. We just set up the values. */ | ||
736 | lp->tx_cmd_link = IDLELOOP + 4; | ||
737 | lp->tx_head = lp->tx_reap = TX_BUF_START; | ||
738 | |||
739 | init_rx_bufs(dev); | ||
740 | |||
741 | /* Start the 586 by releasing the reset line, but leave loopback. */ | ||
742 | outb(0xA0, ioaddr + MISC_CTRL); | ||
743 | |||
744 | /* This was time consuming to track down: you need to give two channel | ||
745 | attention signals to reliably start up the i82586. */ | ||
746 | outb(0, ioaddr + SIGNAL_CA); | ||
747 | |||
748 | { | ||
749 | int boguscnt = 50; | ||
750 | while (readw(shmem+iSCB_STATUS) == 0) | ||
751 | if (--boguscnt == 0) { | ||
752 | pr_warning("%s: i82586 initialization timed out with status %04x, cmd %04x.\n", | ||
753 | dev->name, readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD)); | ||
754 | break; | ||
755 | } | ||
756 | /* Issue channel-attn -- the 82586 won't start. */ | ||
757 | outb(0, ioaddr + SIGNAL_CA); | ||
758 | } | ||
759 | |||
760 | /* Disable loopback and enable interrupts. */ | ||
761 | outb(0x84, ioaddr + MISC_CTRL); | ||
762 | if (net_debug > 4) | ||
763 | pr_debug("%s: Initialized 82586, status %04x.\n", dev->name, | ||
764 | readw(shmem+iSCB_STATUS)); | ||
765 | } | ||
766 | |||
767 | static void hardware_send_packet(struct net_device *dev, void *buf, short length, short pad) | ||
768 | { | ||
769 | struct net_local *lp = netdev_priv(dev); | ||
770 | short ioaddr = dev->base_addr; | ||
771 | ushort tx_block = lp->tx_head; | ||
772 | void __iomem *write_ptr = lp->base + tx_block; | ||
773 | static char padding[ETH_ZLEN]; | ||
774 | |||
775 | /* Set the write pointer to the Tx block, and put out the header. */ | ||
776 | writew(0x0000,write_ptr); /* Tx status */ | ||
777 | writew(CMD_INTR|CmdTx,write_ptr+=2); /* Tx command */ | ||
778 | writew(tx_block+16,write_ptr+=2); /* Next command is a NoOp. */ | ||
779 | writew(tx_block+8,write_ptr+=2); /* Data Buffer offset. */ | ||
780 | |||
781 | /* Output the data buffer descriptor. */ | ||
782 | writew((pad + length) | 0x8000,write_ptr+=2); /* Byte count parameter. */ | ||
783 | writew(-1,write_ptr+=2); /* No next data buffer. */ | ||
784 | writew(tx_block+22+SCB_BASE,write_ptr+=2); /* Buffer follows the NoOp command. */ | ||
785 | writew(0x0000,write_ptr+=2); /* Buffer address high bits (always zero). */ | ||
786 | |||
787 | /* Output the Loop-back NoOp command. */ | ||
788 | writew(0x0000,write_ptr+=2); /* Tx status */ | ||
789 | writew(CmdNOp,write_ptr+=2); /* Tx command */ | ||
790 | writew(tx_block+16,write_ptr+=2); /* Next is myself. */ | ||
791 | |||
792 | /* Output the packet at the write pointer. */ | ||
793 | memcpy_toio(write_ptr+2, buf, length); | ||
794 | if (pad) | ||
795 | memcpy_toio(write_ptr+length+2, padding, pad); | ||
796 | |||
797 | /* Set the old command link pointing to this send packet. */ | ||
798 | writew(tx_block,lp->base + lp->tx_cmd_link); | ||
799 | lp->tx_cmd_link = tx_block + 20; | ||
800 | |||
801 | /* Set the next free tx region. */ | ||
802 | lp->tx_head = tx_block + TX_BUF_SIZE; | ||
803 | if (lp->tx_head > RX_BUF_START - TX_BUF_SIZE) | ||
804 | lp->tx_head = TX_BUF_START; | ||
805 | |||
806 | if (net_debug > 4) { | ||
807 | pr_debug("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n", | ||
808 | dev->name, ioaddr, length, tx_block, lp->tx_head); | ||
809 | } | ||
810 | |||
811 | /* Grimly block further packets if there has been insufficient reaping. */ | ||
812 | if (++lp->tx_pkts_in_ring < NUM_TX_BUFS) | ||
813 | netif_wake_queue(dev); | ||
814 | } | ||
815 | |||
816 | static void el16_rx(struct net_device *dev) | ||
817 | { | ||
818 | struct net_local *lp = netdev_priv(dev); | ||
819 | void __iomem *shmem = lp->base; | ||
820 | ushort rx_head = lp->rx_head; | ||
821 | ushort rx_tail = lp->rx_tail; | ||
822 | ushort boguscount = 10; | ||
823 | short frame_status; | ||
824 | |||
825 | while ((frame_status = readw(shmem+rx_head)) < 0) { /* Command complete */ | ||
826 | void __iomem *read_frame = lp->base + rx_head; | ||
827 | ushort rfd_cmd = readw(read_frame+2); | ||
828 | ushort next_rx_frame = readw(read_frame+4); | ||
829 | ushort data_buffer_addr = readw(read_frame+6); | ||
830 | void __iomem *data_frame = lp->base + data_buffer_addr; | ||
831 | ushort pkt_len = readw(data_frame); | ||
832 | |||
833 | if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22 || | ||
834 | (pkt_len & 0xC000) != 0xC000) { | ||
835 | pr_err("%s: Rx frame at %#x corrupted, " | ||
836 | "status %04x cmd %04x next %04x " | ||
837 | "data-buf @%04x %04x.\n", | ||
838 | dev->name, rx_head, frame_status, rfd_cmd, | ||
839 | next_rx_frame, data_buffer_addr, pkt_len); | ||
840 | } else if ((frame_status & 0x2000) == 0) { | ||
841 | /* Frame Rxed, but with error. */ | ||
842 | dev->stats.rx_errors++; | ||
843 | if (frame_status & 0x0800) dev->stats.rx_crc_errors++; | ||
844 | if (frame_status & 0x0400) dev->stats.rx_frame_errors++; | ||
845 | if (frame_status & 0x0200) dev->stats.rx_fifo_errors++; | ||
846 | if (frame_status & 0x0100) dev->stats.rx_over_errors++; | ||
847 | if (frame_status & 0x0080) dev->stats.rx_length_errors++; | ||
848 | } else { | ||
849 | /* Malloc up new buffer. */ | ||
850 | struct sk_buff *skb; | ||
851 | |||
852 | pkt_len &= 0x3fff; | ||
853 | skb = netdev_alloc_skb(dev, pkt_len + 2); | ||
854 | if (skb == NULL) { | ||
855 | pr_err("%s: Memory squeeze, dropping packet.\n", | ||
856 | dev->name); | ||
857 | dev->stats.rx_dropped++; | ||
858 | break; | ||
859 | } | ||
860 | |||
861 | skb_reserve(skb,2); | ||
862 | |||
863 | /* 'skb->data' points to the start of sk_buff data area. */ | ||
864 | memcpy_fromio(skb_put(skb,pkt_len), data_frame + 10, pkt_len); | ||
865 | |||
866 | skb->protocol=eth_type_trans(skb,dev); | ||
867 | netif_rx(skb); | ||
868 | dev->stats.rx_packets++; | ||
869 | dev->stats.rx_bytes += pkt_len; | ||
870 | } | ||
871 | |||
872 | /* Clear the status word and set End-of-List on the rx frame. */ | ||
873 | writew(0,read_frame); | ||
874 | writew(0xC000,read_frame+2); | ||
875 | /* Clear the end-of-list on the prev. RFD. */ | ||
876 | writew(0x0000,lp->base + rx_tail + 2); | ||
877 | |||
878 | rx_tail = rx_head; | ||
879 | rx_head = next_rx_frame; | ||
880 | if (--boguscount == 0) | ||
881 | break; | ||
882 | } | ||
883 | |||
884 | lp->rx_head = rx_head; | ||
885 | lp->rx_tail = rx_tail; | ||
886 | } | ||
887 | |||
888 | static void netdev_get_drvinfo(struct net_device *dev, | ||
889 | struct ethtool_drvinfo *info) | ||
890 | { | ||
891 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); | ||
892 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); | ||
893 | snprintf(info->bus_info, sizeof(info->bus_info), "ISA 0x%lx", | ||
894 | dev->base_addr); | ||
895 | } | ||
896 | |||
897 | static u32 netdev_get_msglevel(struct net_device *dev) | ||
898 | { | ||
899 | return debug; | ||
900 | } | ||
901 | |||
902 | static void netdev_set_msglevel(struct net_device *dev, u32 level) | ||
903 | { | ||
904 | debug = level; | ||
905 | } | ||
906 | |||
907 | static const struct ethtool_ops netdev_ethtool_ops = { | ||
908 | .get_drvinfo = netdev_get_drvinfo, | ||
909 | .get_msglevel = netdev_get_msglevel, | ||
910 | .set_msglevel = netdev_set_msglevel, | ||
911 | }; | ||
912 | |||
913 | #ifdef MODULE | ||
914 | static struct net_device *dev_3c507; | ||
915 | module_param(io, int, 0); | ||
916 | module_param(irq, int, 0); | ||
917 | MODULE_PARM_DESC(io, "EtherLink16 I/O base address"); | ||
918 | MODULE_PARM_DESC(irq, "(ignored)"); | ||
919 | |||
920 | int __init init_module(void) | ||
921 | { | ||
922 | if (io == 0) | ||
923 | pr_notice("3c507: You should not use auto-probing with insmod!\n"); | ||
924 | dev_3c507 = el16_probe(-1); | ||
925 | return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0; | ||
926 | } | ||
927 | |||
928 | void __exit | ||
929 | cleanup_module(void) | ||
930 | { | ||
931 | struct net_device *dev = dev_3c507; | ||
932 | unregister_netdev(dev); | ||
933 | free_irq(dev->irq, dev); | ||
934 | iounmap(((struct net_local *)netdev_priv(dev))->base); | ||
935 | release_region(dev->base_addr, EL16_IO_EXTENT); | ||
936 | free_netdev(dev); | ||
937 | } | ||
938 | #endif /* MODULE */ | ||
939 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/ethernet/i825xx/Kconfig b/drivers/net/ethernet/i825xx/Kconfig index 46edb81bbedb..b800a94fc875 100644 --- a/drivers/net/ethernet/i825xx/Kconfig +++ b/drivers/net/ethernet/i825xx/Kconfig | |||
@@ -20,29 +20,6 @@ config NET_VENDOR_I825XX | |||
20 | 20 | ||
21 | if NET_VENDOR_I825XX | 21 | if NET_VENDOR_I825XX |
22 | 22 | ||
23 | config ELPLUS | ||
24 | tristate "3c505 \"EtherLink Plus\" support" | ||
25 | depends on ISA && ISA_DMA_API | ||
26 | ---help--- | ||
27 | Information about this network (Ethernet) card can be found in | ||
28 | <file:Documentation/networking/3c505.txt>. If you have a card of | ||
29 | this type, say Y and read the Ethernet-HOWTO, available from | ||
30 | <http://www.tldp.org/docs.html#howto>. | ||
31 | |||
32 | To compile this driver as a module, choose M here. The module | ||
33 | will be called 3c505. | ||
34 | |||
35 | config EL16 | ||
36 | tristate "3c507 \"EtherLink 16\" support (EXPERIMENTAL)" | ||
37 | depends on ISA && EXPERIMENTAL | ||
38 | ---help--- | ||
39 | If you have a network (Ethernet) card of this type, say Y and read | ||
40 | the Ethernet-HOWTO, available from | ||
41 | <http://www.tldp.org/docs.html#howto>. | ||
42 | |||
43 | To compile this driver as a module, choose M here. The module | ||
44 | will be called 3c507. | ||
45 | |||
46 | config ARM_ETHER1 | 23 | config ARM_ETHER1 |
47 | tristate "Acorn Ether1 support" | 24 | tristate "Acorn Ether1 support" |
48 | depends on ARM && ARCH_ACORN | 25 | depends on ARM && ARCH_ACORN |
diff --git a/drivers/net/ethernet/i825xx/Makefile b/drivers/net/ethernet/i825xx/Makefile index 4f01584bd897..bc81e14ed5bd 100644 --- a/drivers/net/ethernet/i825xx/Makefile +++ b/drivers/net/ethernet/i825xx/Makefile | |||
@@ -5,8 +5,6 @@ | |||
5 | obj-$(CONFIG_ARM_ETHER1) += ether1.o | 5 | obj-$(CONFIG_ARM_ETHER1) += ether1.o |
6 | obj-$(CONFIG_EEXPRESS) += eexpress.o | 6 | obj-$(CONFIG_EEXPRESS) += eexpress.o |
7 | obj-$(CONFIG_EEXPRESS_PRO) += eepro.o | 7 | obj-$(CONFIG_EEXPRESS_PRO) += eepro.o |
8 | obj-$(CONFIG_ELPLUS) += 3c505.o | ||
9 | obj-$(CONFIG_EL16) += 3c507.o | ||
10 | obj-$(CONFIG_NI52) += ni52.o | 8 | obj-$(CONFIG_NI52) += ni52.o |
11 | obj-$(CONFIG_SUN3_82586) += sun3_82586.o | 9 | obj-$(CONFIG_SUN3_82586) += sun3_82586.o |
12 | obj-$(CONFIG_ZNET) += znet.o | 10 | obj-$(CONFIG_ZNET) += znet.o |