diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-04-02 09:20:12 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-08-10 22:54:25 -0400 |
commit | 644570b830266ff33ff5f3542b9c838f93a55ea6 (patch) | |
tree | b19c680ce1b1e4cd15465c74aa335459068c033f /drivers/net/ethernet | |
parent | b955f6ca776f3bab3d1e2c5fb1d247b203cbda14 (diff) |
8390: Move the 8390 related drivers
Moves the drivers for the National Semi-conductor 8390 chipset into
drivers/net/ethernet/8390/ and the necessary Kconfig and Makefile
changes.
CC: Donald Becker <becker@scyld.com>
CC: Paul Gortmaker <paul.gortmaker@windriver.com>
CC: Alain Malek <alain.malek@cryogen.com>
CC: Peter De Schrijver <p2@mind.be>
CC: "David Huggins-Daines" <dhd@debian.org>
CC: Wim Dumon <wimpie@kotnet.org>
CC: Yoshinori Sato <ysato@users.sourceforge.jp>
CC: David Hinds <dahinds@users.sourceforge.net>
CC: Russell King <linux@arm.linux.org.uk>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet')
34 files changed, 19133 insertions, 0 deletions
diff --git a/drivers/net/ethernet/8390/3c503.c b/drivers/net/ethernet/8390/3c503.c new file mode 100644 index 000000000000..84e68f1b9adf --- /dev/null +++ b/drivers/net/ethernet/8390/3c503.c | |||
@@ -0,0 +1,778 @@ | |||
1 | /* 3c503.c: A shared-memory NS8390 ethernet driver for linux. */ | ||
2 | /* | ||
3 | Written 1992-94 by Donald Becker. | ||
4 | |||
5 | Copyright 1993 United States Government as represented by the | ||
6 | Director, National Security Agency. This software may be used and | ||
7 | distributed according to the terms of the GNU General Public License, | ||
8 | incorporated herein by reference. | ||
9 | |||
10 | The author may be reached as becker@scyld.com, or C/O | ||
11 | Scyld Computing Corporation | ||
12 | 410 Severn Ave., Suite 210 | ||
13 | Annapolis MD 21403 | ||
14 | |||
15 | |||
16 | This driver should work with the 3c503 and 3c503/16. It should be used | ||
17 | in shared memory mode for best performance, although it may also work | ||
18 | in programmed-I/O mode. | ||
19 | |||
20 | Sources: | ||
21 | EtherLink II Technical Reference Manual, | ||
22 | EtherLink II/16 Technical Reference Manual Supplement, | ||
23 | 3Com Corporation, 5400 Bayfront Plaza, Santa Clara CA 95052-8145 | ||
24 | |||
25 | The Crynwr 3c503 packet driver. | ||
26 | |||
27 | Changelog: | ||
28 | |||
29 | Paul Gortmaker : add support for the 2nd 8kB of RAM on 16 bit cards. | ||
30 | Paul Gortmaker : multiple card support for module users. | ||
31 | rjohnson@analogic.com : Fix up PIO interface for efficient operation. | ||
32 | Jeff Garzik : ethtool support | ||
33 | |||
34 | */ | ||
35 | |||
36 | #define DRV_NAME "3c503" | ||
37 | #define DRV_VERSION "1.10a" | ||
38 | #define DRV_RELDATE "11/17/2001" | ||
39 | |||
40 | |||
41 | static const char version[] = | ||
42 | DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Donald Becker (becker@scyld.com)\n"; | ||
43 | |||
44 | #include <linux/module.h> | ||
45 | #include <linux/kernel.h> | ||
46 | #include <linux/errno.h> | ||
47 | #include <linux/string.h> | ||
48 | #include <linux/delay.h> | ||
49 | #include <linux/netdevice.h> | ||
50 | #include <linux/etherdevice.h> | ||
51 | #include <linux/init.h> | ||
52 | #include <linux/interrupt.h> | ||
53 | #include <linux/ethtool.h> | ||
54 | |||
55 | #include <asm/uaccess.h> | ||
56 | #include <asm/io.h> | ||
57 | #include <asm/system.h> | ||
58 | #include <asm/byteorder.h> | ||
59 | |||
60 | #include "8390.h" | ||
61 | #include "3c503.h" | ||
62 | #define WRD_COUNT 4 | ||
63 | |||
64 | static int el2_pio_probe(struct net_device *dev); | ||
65 | static int el2_probe1(struct net_device *dev, int ioaddr); | ||
66 | |||
67 | /* A zero-terminated list of I/O addresses to be probed in PIO mode. */ | ||
68 | static unsigned int netcard_portlist[] __initdata = | ||
69 | { 0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0}; | ||
70 | |||
71 | #define EL2_IO_EXTENT 16 | ||
72 | |||
73 | static int el2_open(struct net_device *dev); | ||
74 | static int el2_close(struct net_device *dev); | ||
75 | static void el2_reset_8390(struct net_device *dev); | ||
76 | static void el2_init_card(struct net_device *dev); | ||
77 | static void el2_block_output(struct net_device *dev, int count, | ||
78 | const unsigned char *buf, int start_page); | ||
79 | static void el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, | ||
80 | int ring_offset); | ||
81 | static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
82 | int ring_page); | ||
83 | static const struct ethtool_ops netdev_ethtool_ops; | ||
84 | |||
85 | |||
86 | /* This routine probes for a memory-mapped 3c503 board by looking for | ||
87 | the "location register" at the end of the jumpered boot PROM space. | ||
88 | This works even if a PROM isn't there. | ||
89 | |||
90 | If the ethercard isn't found there is an optional probe for | ||
91 | ethercard jumpered to programmed-I/O mode. | ||
92 | */ | ||
93 | static int __init do_el2_probe(struct net_device *dev) | ||
94 | { | ||
95 | int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0}; | ||
96 | int base_addr = dev->base_addr; | ||
97 | int irq = dev->irq; | ||
98 | |||
99 | if (base_addr > 0x1ff) /* Check a single specified location. */ | ||
100 | return el2_probe1(dev, base_addr); | ||
101 | else if (base_addr != 0) /* Don't probe at all. */ | ||
102 | return -ENXIO; | ||
103 | |||
104 | for (addr = addrs; *addr; addr++) { | ||
105 | void __iomem *p = ioremap(*addr, 1); | ||
106 | unsigned base_bits; | ||
107 | int i; | ||
108 | |||
109 | if (!p) | ||
110 | continue; | ||
111 | base_bits = readb(p); | ||
112 | iounmap(p); | ||
113 | i = ffs(base_bits) - 1; | ||
114 | if (i == -1 || base_bits != (1 << i)) | ||
115 | continue; | ||
116 | if (el2_probe1(dev, netcard_portlist[i]) == 0) | ||
117 | return 0; | ||
118 | dev->irq = irq; | ||
119 | } | ||
120 | #if ! defined(no_probe_nonshared_memory) | ||
121 | return el2_pio_probe(dev); | ||
122 | #else | ||
123 | return -ENODEV; | ||
124 | #endif | ||
125 | } | ||
126 | |||
127 | /* Try all of the locations that aren't obviously empty. This touches | ||
128 | a lot of locations, and is much riskier than the code above. */ | ||
129 | static int __init | ||
130 | el2_pio_probe(struct net_device *dev) | ||
131 | { | ||
132 | int i; | ||
133 | int base_addr = dev->base_addr; | ||
134 | int irq = dev->irq; | ||
135 | |||
136 | if (base_addr > 0x1ff) /* Check a single specified location. */ | ||
137 | return el2_probe1(dev, base_addr); | ||
138 | else if (base_addr != 0) /* Don't probe at all. */ | ||
139 | return -ENXIO; | ||
140 | |||
141 | for (i = 0; netcard_portlist[i]; i++) { | ||
142 | if (el2_probe1(dev, netcard_portlist[i]) == 0) | ||
143 | return 0; | ||
144 | dev->irq = irq; | ||
145 | } | ||
146 | |||
147 | return -ENODEV; | ||
148 | } | ||
149 | |||
150 | #ifndef MODULE | ||
151 | struct net_device * __init el2_probe(int unit) | ||
152 | { | ||
153 | struct net_device *dev = alloc_eip_netdev(); | ||
154 | int err; | ||
155 | |||
156 | if (!dev) | ||
157 | return ERR_PTR(-ENOMEM); | ||
158 | |||
159 | sprintf(dev->name, "eth%d", unit); | ||
160 | netdev_boot_setup_check(dev); | ||
161 | |||
162 | err = do_el2_probe(dev); | ||
163 | if (err) | ||
164 | goto out; | ||
165 | return dev; | ||
166 | out: | ||
167 | free_netdev(dev); | ||
168 | return ERR_PTR(err); | ||
169 | } | ||
170 | #endif | ||
171 | |||
172 | static const struct net_device_ops el2_netdev_ops = { | ||
173 | .ndo_open = el2_open, | ||
174 | .ndo_stop = el2_close, | ||
175 | |||
176 | .ndo_start_xmit = eip_start_xmit, | ||
177 | .ndo_tx_timeout = eip_tx_timeout, | ||
178 | .ndo_get_stats = eip_get_stats, | ||
179 | .ndo_set_multicast_list = eip_set_multicast_list, | ||
180 | .ndo_validate_addr = eth_validate_addr, | ||
181 | .ndo_set_mac_address = eth_mac_addr, | ||
182 | .ndo_change_mtu = eth_change_mtu, | ||
183 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
184 | .ndo_poll_controller = eip_poll, | ||
185 | #endif | ||
186 | }; | ||
187 | |||
188 | /* Probe for the Etherlink II card at I/O port base IOADDR, | ||
189 | returning non-zero on success. If found, set the station | ||
190 | address and memory parameters in DEVICE. */ | ||
191 | static int __init | ||
192 | el2_probe1(struct net_device *dev, int ioaddr) | ||
193 | { | ||
194 | int i, iobase_reg, membase_reg, saved_406, wordlength, retval; | ||
195 | static unsigned version_printed; | ||
196 | unsigned long vendor_id; | ||
197 | |||
198 | if (!request_region(ioaddr, EL2_IO_EXTENT, DRV_NAME)) | ||
199 | return -EBUSY; | ||
200 | |||
201 | if (!request_region(ioaddr + 0x400, 8, DRV_NAME)) { | ||
202 | retval = -EBUSY; | ||
203 | goto out; | ||
204 | } | ||
205 | |||
206 | /* Reset and/or avoid any lurking NE2000 */ | ||
207 | if (inb(ioaddr + 0x408) == 0xff) { | ||
208 | mdelay(1); | ||
209 | retval = -ENODEV; | ||
210 | goto out1; | ||
211 | } | ||
212 | |||
213 | /* We verify that it's a 3C503 board by checking the first three octets | ||
214 | of its ethernet address. */ | ||
215 | iobase_reg = inb(ioaddr+0x403); | ||
216 | membase_reg = inb(ioaddr+0x404); | ||
217 | /* ASIC location registers should be 0 or have only a single bit set. */ | ||
218 | if ((iobase_reg & (iobase_reg - 1)) || | ||
219 | (membase_reg & (membase_reg - 1))) { | ||
220 | retval = -ENODEV; | ||
221 | goto out1; | ||
222 | } | ||
223 | saved_406 = inb_p(ioaddr + 0x406); | ||
224 | outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */ | ||
225 | outb_p(ECNTRL_THIN, ioaddr + 0x406); | ||
226 | /* Map the station addr PROM into the lower I/O ports. We now check | ||
227 | for both the old and new 3Com prefix */ | ||
228 | outb(ECNTRL_SAPROM|ECNTRL_THIN, ioaddr + 0x406); | ||
229 | vendor_id = inb(ioaddr)*0x10000 + inb(ioaddr + 1)*0x100 + inb(ioaddr + 2); | ||
230 | if ((vendor_id != OLD_3COM_ID) && (vendor_id != NEW_3COM_ID)) { | ||
231 | /* Restore the register we frobbed. */ | ||
232 | outb(saved_406, ioaddr + 0x406); | ||
233 | retval = -ENODEV; | ||
234 | goto out1; | ||
235 | } | ||
236 | |||
237 | if (ei_debug && version_printed++ == 0) | ||
238 | pr_debug("%s", version); | ||
239 | |||
240 | dev->base_addr = ioaddr; | ||
241 | |||
242 | pr_info("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr); | ||
243 | |||
244 | /* Retrieve and print the ethernet address. */ | ||
245 | for (i = 0; i < 6; i++) | ||
246 | dev->dev_addr[i] = inb(ioaddr + i); | ||
247 | pr_cont("%pM", dev->dev_addr); | ||
248 | |||
249 | /* Map the 8390 back into the window. */ | ||
250 | outb(ECNTRL_THIN, ioaddr + 0x406); | ||
251 | |||
252 | /* Check for EL2/16 as described in tech. man. */ | ||
253 | outb_p(E8390_PAGE0, ioaddr + E8390_CMD); | ||
254 | outb_p(0, ioaddr + EN0_DCFG); | ||
255 | outb_p(E8390_PAGE2, ioaddr + E8390_CMD); | ||
256 | wordlength = inb_p(ioaddr + EN0_DCFG) & ENDCFG_WTS; | ||
257 | outb_p(E8390_PAGE0, ioaddr + E8390_CMD); | ||
258 | |||
259 | /* Probe for, turn on and clear the board's shared memory. */ | ||
260 | if (ei_debug > 2) | ||
261 | pr_cont(" memory jumpers %2.2x ", membase_reg); | ||
262 | outb(EGACFR_NORM, ioaddr + 0x405); /* Enable RAM */ | ||
263 | |||
264 | /* This should be probed for (or set via an ioctl()) at run-time. | ||
265 | Right now we use a sleazy hack to pass in the interface number | ||
266 | at boot-time via the low bits of the mem_end field. That value is | ||
267 | unused, and the low bits would be discarded even if it was used. */ | ||
268 | #if defined(EI8390_THICK) || defined(EL2_AUI) | ||
269 | ei_status.interface_num = 1; | ||
270 | #else | ||
271 | ei_status.interface_num = dev->mem_end & 0xf; | ||
272 | #endif | ||
273 | pr_cont(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex"); | ||
274 | |||
275 | if ((membase_reg & 0xf0) == 0) { | ||
276 | dev->mem_start = 0; | ||
277 | ei_status.name = "3c503-PIO"; | ||
278 | ei_status.mem = NULL; | ||
279 | } else { | ||
280 | dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) + | ||
281 | ((membase_reg & 0xA0) ? 0x4000 : 0); | ||
282 | #define EL2_MEMSIZE (EL2_MB1_STOP_PG - EL2_MB1_START_PG)*256 | ||
283 | ei_status.mem = ioremap(dev->mem_start, EL2_MEMSIZE); | ||
284 | |||
285 | #ifdef EL2MEMTEST | ||
286 | /* This has never found an error, but someone might care. | ||
287 | Note that it only tests the 2nd 8kB on 16kB 3c503/16 | ||
288 | cards between card addr. 0x2000 and 0x3fff. */ | ||
289 | { /* Check the card's memory. */ | ||
290 | void __iomem *mem_base = ei_status.mem; | ||
291 | unsigned int test_val = 0xbbadf00d; | ||
292 | writel(0xba5eba5e, mem_base); | ||
293 | for (i = sizeof(test_val); i < EL2_MEMSIZE; i+=sizeof(test_val)) { | ||
294 | writel(test_val, mem_base + i); | ||
295 | if (readl(mem_base) != 0xba5eba5e || | ||
296 | readl(mem_base + i) != test_val) { | ||
297 | pr_warning("3c503: memory failure or memory address conflict.\n"); | ||
298 | dev->mem_start = 0; | ||
299 | ei_status.name = "3c503-PIO"; | ||
300 | iounmap(mem_base); | ||
301 | ei_status.mem = NULL; | ||
302 | break; | ||
303 | } | ||
304 | test_val += 0x55555555; | ||
305 | writel(0, mem_base + i); | ||
306 | } | ||
307 | } | ||
308 | #endif /* EL2MEMTEST */ | ||
309 | |||
310 | if (dev->mem_start) | ||
311 | dev->mem_end = dev->mem_start + EL2_MEMSIZE; | ||
312 | |||
313 | if (wordlength) { /* No Tx pages to skip over to get to Rx */ | ||
314 | ei_status.priv = 0; | ||
315 | ei_status.name = "3c503/16"; | ||
316 | } else { | ||
317 | ei_status.priv = TX_PAGES * 256; | ||
318 | ei_status.name = "3c503"; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | /* | ||
323 | Divide up the memory on the card. This is the same regardless of | ||
324 | whether shared-mem or PIO is used. For 16 bit cards (16kB RAM), | ||
325 | we use the entire 8k of bank1 for an Rx ring. We only use 3k | ||
326 | of the bank0 for 2 full size Tx packet slots. For 8 bit cards, | ||
327 | (8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining | ||
328 | 5kB for an Rx ring. */ | ||
329 | |||
330 | if (wordlength) { | ||
331 | ei_status.tx_start_page = EL2_MB0_START_PG; | ||
332 | ei_status.rx_start_page = EL2_MB1_START_PG; | ||
333 | } else { | ||
334 | ei_status.tx_start_page = EL2_MB1_START_PG; | ||
335 | ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES; | ||
336 | } | ||
337 | |||
338 | /* Finish setting the board's parameters. */ | ||
339 | ei_status.stop_page = EL2_MB1_STOP_PG; | ||
340 | ei_status.word16 = wordlength; | ||
341 | ei_status.reset_8390 = el2_reset_8390; | ||
342 | ei_status.get_8390_hdr = el2_get_8390_hdr; | ||
343 | ei_status.block_input = el2_block_input; | ||
344 | ei_status.block_output = el2_block_output; | ||
345 | |||
346 | if (dev->irq == 2) | ||
347 | dev->irq = 9; | ||
348 | else if (dev->irq > 5 && dev->irq != 9) { | ||
349 | pr_warning("3c503: configured interrupt %d invalid, will use autoIRQ.\n", | ||
350 | dev->irq); | ||
351 | dev->irq = 0; | ||
352 | } | ||
353 | |||
354 | ei_status.saved_irq = dev->irq; | ||
355 | |||
356 | dev->netdev_ops = &el2_netdev_ops; | ||
357 | dev->ethtool_ops = &netdev_ethtool_ops; | ||
358 | |||
359 | retval = register_netdev(dev); | ||
360 | if (retval) | ||
361 | goto out1; | ||
362 | |||
363 | if (dev->mem_start) | ||
364 | pr_info("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n", | ||
365 | dev->name, ei_status.name, (wordlength+1)<<3, | ||
366 | dev->mem_start, dev->mem_end-1); | ||
367 | |||
368 | else | ||
369 | { | ||
370 | ei_status.tx_start_page = EL2_MB1_START_PG; | ||
371 | ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES; | ||
372 | pr_info("%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n", | ||
373 | dev->name, ei_status.name, (wordlength+1)<<3); | ||
374 | } | ||
375 | release_region(ioaddr + 0x400, 8); | ||
376 | return 0; | ||
377 | out1: | ||
378 | release_region(ioaddr + 0x400, 8); | ||
379 | out: | ||
380 | release_region(ioaddr, EL2_IO_EXTENT); | ||
381 | return retval; | ||
382 | } | ||
383 | |||
384 | static irqreturn_t el2_probe_interrupt(int irq, void *seen) | ||
385 | { | ||
386 | *(bool *)seen = true; | ||
387 | return IRQ_HANDLED; | ||
388 | } | ||
389 | |||
390 | static int | ||
391 | el2_open(struct net_device *dev) | ||
392 | { | ||
393 | int retval; | ||
394 | |||
395 | if (dev->irq < 2) { | ||
396 | static const int irqlist[] = {5, 9, 3, 4, 0}; | ||
397 | const int *irqp = irqlist; | ||
398 | |||
399 | outb(EGACFR_NORM, E33G_GACFR); /* Enable RAM and interrupts. */ | ||
400 | do { | ||
401 | bool seen; | ||
402 | |||
403 | retval = request_irq(*irqp, el2_probe_interrupt, 0, | ||
404 | dev->name, &seen); | ||
405 | if (retval == -EBUSY) | ||
406 | continue; | ||
407 | if (retval < 0) | ||
408 | goto err_disable; | ||
409 | |||
410 | /* Twinkle the interrupt, and check if it's seen. */ | ||
411 | seen = false; | ||
412 | smp_wmb(); | ||
413 | outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR); | ||
414 | outb_p(0x00, E33G_IDCFR); | ||
415 | msleep(1); | ||
416 | free_irq(*irqp, &seen); | ||
417 | if (!seen) | ||
418 | continue; | ||
419 | |||
420 | retval = request_irq(dev->irq = *irqp, eip_interrupt, 0, | ||
421 | dev->name, dev); | ||
422 | if (retval == -EBUSY) | ||
423 | continue; | ||
424 | if (retval < 0) | ||
425 | goto err_disable; | ||
426 | break; | ||
427 | } while (*++irqp); | ||
428 | |||
429 | if (*irqp == 0) { | ||
430 | err_disable: | ||
431 | outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */ | ||
432 | return -EAGAIN; | ||
433 | } | ||
434 | } else { | ||
435 | if ((retval = request_irq(dev->irq, eip_interrupt, 0, dev->name, dev))) { | ||
436 | return retval; | ||
437 | } | ||
438 | } | ||
439 | |||
440 | el2_init_card(dev); | ||
441 | eip_open(dev); | ||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | static int | ||
446 | el2_close(struct net_device *dev) | ||
447 | { | ||
448 | free_irq(dev->irq, dev); | ||
449 | dev->irq = ei_status.saved_irq; | ||
450 | outb(EGACFR_IRQOFF, E33G_GACFR); /* disable interrupts. */ | ||
451 | |||
452 | eip_close(dev); | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | /* This is called whenever we have a unrecoverable failure: | ||
457 | transmit timeout | ||
458 | Bad ring buffer packet header | ||
459 | */ | ||
460 | static void | ||
461 | el2_reset_8390(struct net_device *dev) | ||
462 | { | ||
463 | if (ei_debug > 1) { | ||
464 | pr_debug("%s: Resetting the 3c503 board...", dev->name); | ||
465 | pr_cont(" %#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR), | ||
466 | E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR)); | ||
467 | } | ||
468 | outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL); | ||
469 | ei_status.txing = 0; | ||
470 | outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL); | ||
471 | el2_init_card(dev); | ||
472 | if (ei_debug > 1) | ||
473 | pr_cont("done\n"); | ||
474 | } | ||
475 | |||
476 | /* Initialize the 3c503 GA registers after a reset. */ | ||
477 | static void | ||
478 | el2_init_card(struct net_device *dev) | ||
479 | { | ||
480 | /* Unmap the station PROM and select the DIX or BNC connector. */ | ||
481 | outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL); | ||
482 | |||
483 | /* Set ASIC copy of rx's first and last+1 buffer pages */ | ||
484 | /* These must be the same as in the 8390. */ | ||
485 | outb(ei_status.rx_start_page, E33G_STARTPG); | ||
486 | outb(ei_status.stop_page, E33G_STOPPG); | ||
487 | |||
488 | /* Point the vector pointer registers somewhere ?harmless?. */ | ||
489 | outb(0xff, E33G_VP2); /* Point at the ROM restart location 0xffff0 */ | ||
490 | outb(0xff, E33G_VP1); | ||
491 | outb(0x00, E33G_VP0); | ||
492 | /* Turn off all interrupts until we're opened. */ | ||
493 | outb_p(0x00, dev->base_addr + EN0_IMR); | ||
494 | /* Enable IRQs iff started. */ | ||
495 | outb(EGACFR_NORM, E33G_GACFR); | ||
496 | |||
497 | /* Set the interrupt line. */ | ||
498 | outb_p((0x04 << (dev->irq == 9 ? 2 : dev->irq)), E33G_IDCFR); | ||
499 | outb_p((WRD_COUNT << 1), E33G_DRQCNT); /* Set burst size to 8 */ | ||
500 | outb_p(0x20, E33G_DMAAH); /* Put a valid addr in the GA DMA */ | ||
501 | outb_p(0x00, E33G_DMAAL); | ||
502 | return; /* We always succeed */ | ||
503 | } | ||
504 | |||
505 | /* | ||
506 | * Either use the shared memory (if enabled on the board) or put the packet | ||
507 | * out through the ASIC FIFO. | ||
508 | */ | ||
509 | static void | ||
510 | el2_block_output(struct net_device *dev, int count, | ||
511 | const unsigned char *buf, int start_page) | ||
512 | { | ||
513 | unsigned short int *wrd; | ||
514 | int boguscount; /* timeout counter */ | ||
515 | unsigned short word; /* temporary for better machine code */ | ||
516 | void __iomem *base = ei_status.mem; | ||
517 | |||
518 | if (ei_status.word16) /* Tx packets go into bank 0 on EL2/16 card */ | ||
519 | outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR); | ||
520 | else | ||
521 | outb(EGACFR_NORM, E33G_GACFR); | ||
522 | |||
523 | if (base) { /* Shared memory transfer */ | ||
524 | memcpy_toio(base + ((start_page - ei_status.tx_start_page) << 8), | ||
525 | buf, count); | ||
526 | outb(EGACFR_NORM, E33G_GACFR); /* Back to bank1 in case on bank0 */ | ||
527 | return; | ||
528 | } | ||
529 | |||
530 | /* | ||
531 | * No shared memory, put the packet out the other way. | ||
532 | * Set up then start the internal memory transfer to Tx Start Page | ||
533 | */ | ||
534 | |||
535 | word = (unsigned short)start_page; | ||
536 | outb(word&0xFF, E33G_DMAAH); | ||
537 | outb(word>>8, E33G_DMAAL); | ||
538 | |||
539 | outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT | ||
540 | | ECNTRL_START, E33G_CNTRL); | ||
541 | |||
542 | /* | ||
543 | * Here I am going to write data to the FIFO as quickly as possible. | ||
544 | * Note that E33G_FIFOH is defined incorrectly. It is really | ||
545 | * E33G_FIFOL, the lowest port address for both the byte and | ||
546 | * word write. Variable 'count' is NOT checked. Caller must supply a | ||
547 | * valid count. Note that I may write a harmless extra byte to the | ||
548 | * 8390 if the byte-count was not even. | ||
549 | */ | ||
550 | wrd = (unsigned short int *) buf; | ||
551 | count = (count + 1) >> 1; | ||
552 | for(;;) | ||
553 | { | ||
554 | boguscount = 0x1000; | ||
555 | while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0) | ||
556 | { | ||
557 | if(!boguscount--) | ||
558 | { | ||
559 | pr_notice("%s: FIFO blocked in el2_block_output.\n", dev->name); | ||
560 | el2_reset_8390(dev); | ||
561 | goto blocked; | ||
562 | } | ||
563 | } | ||
564 | if(count > WRD_COUNT) | ||
565 | { | ||
566 | outsw(E33G_FIFOH, wrd, WRD_COUNT); | ||
567 | wrd += WRD_COUNT; | ||
568 | count -= WRD_COUNT; | ||
569 | } | ||
570 | else | ||
571 | { | ||
572 | outsw(E33G_FIFOH, wrd, count); | ||
573 | break; | ||
574 | } | ||
575 | } | ||
576 | blocked:; | ||
577 | outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL); | ||
578 | } | ||
579 | |||
580 | /* Read the 4 byte, page aligned 8390 specific header. */ | ||
581 | static void | ||
582 | el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
583 | { | ||
584 | int boguscount; | ||
585 | void __iomem *base = ei_status.mem; | ||
586 | unsigned short word; | ||
587 | |||
588 | if (base) { /* Use the shared memory. */ | ||
589 | void __iomem *hdr_start = base + ((ring_page - EL2_MB1_START_PG)<<8); | ||
590 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
591 | hdr->count = le16_to_cpu(hdr->count); | ||
592 | return; | ||
593 | } | ||
594 | |||
595 | /* | ||
596 | * No shared memory, use programmed I/O. | ||
597 | */ | ||
598 | |||
599 | word = (unsigned short)ring_page; | ||
600 | outb(word&0xFF, E33G_DMAAH); | ||
601 | outb(word>>8, E33G_DMAAL); | ||
602 | |||
603 | outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT | ||
604 | | ECNTRL_START, E33G_CNTRL); | ||
605 | boguscount = 0x1000; | ||
606 | while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0) | ||
607 | { | ||
608 | if(!boguscount--) | ||
609 | { | ||
610 | pr_notice("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name); | ||
611 | memset(hdr, 0x00, sizeof(struct e8390_pkt_hdr)); | ||
612 | el2_reset_8390(dev); | ||
613 | goto blocked; | ||
614 | } | ||
615 | } | ||
616 | insw(E33G_FIFOH, hdr, (sizeof(struct e8390_pkt_hdr))>> 1); | ||
617 | blocked:; | ||
618 | outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL); | ||
619 | } | ||
620 | |||
621 | |||
622 | static void | ||
623 | el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
624 | { | ||
625 | int boguscount = 0; | ||
626 | void __iomem *base = ei_status.mem; | ||
627 | unsigned short int *buf; | ||
628 | unsigned short word; | ||
629 | |||
630 | /* Maybe enable shared memory just be to be safe... nahh.*/ | ||
631 | if (base) { /* Use the shared memory. */ | ||
632 | ring_offset -= (EL2_MB1_START_PG<<8); | ||
633 | if (ring_offset + count > EL2_MEMSIZE) { | ||
634 | /* We must wrap the input move. */ | ||
635 | int semi_count = EL2_MEMSIZE - ring_offset; | ||
636 | memcpy_fromio(skb->data, base + ring_offset, semi_count); | ||
637 | count -= semi_count; | ||
638 | memcpy_fromio(skb->data + semi_count, base + ei_status.priv, count); | ||
639 | } else { | ||
640 | memcpy_fromio(skb->data, base + ring_offset, count); | ||
641 | } | ||
642 | return; | ||
643 | } | ||
644 | |||
645 | /* | ||
646 | * No shared memory, use programmed I/O. | ||
647 | */ | ||
648 | word = (unsigned short) ring_offset; | ||
649 | outb(word>>8, E33G_DMAAH); | ||
650 | outb(word&0xFF, E33G_DMAAL); | ||
651 | |||
652 | outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT | ||
653 | | ECNTRL_START, E33G_CNTRL); | ||
654 | |||
655 | /* | ||
656 | * Here I also try to get data as fast as possible. I am betting that I | ||
657 | * can read one extra byte without clobbering anything in the kernel because | ||
658 | * this would only occur on an odd byte-count and allocation of skb->data | ||
659 | * is word-aligned. Variable 'count' is NOT checked. Caller must check | ||
660 | * for a valid count. | ||
661 | * [This is currently quite safe.... but if one day the 3c503 explodes | ||
662 | * you know where to come looking ;)] | ||
663 | */ | ||
664 | |||
665 | buf = (unsigned short int *) skb->data; | ||
666 | count = (count + 1) >> 1; | ||
667 | for(;;) | ||
668 | { | ||
669 | boguscount = 0x1000; | ||
670 | while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0) | ||
671 | { | ||
672 | if(!boguscount--) | ||
673 | { | ||
674 | pr_notice("%s: FIFO blocked in el2_block_input.\n", dev->name); | ||
675 | el2_reset_8390(dev); | ||
676 | goto blocked; | ||
677 | } | ||
678 | } | ||
679 | if(count > WRD_COUNT) | ||
680 | { | ||
681 | insw(E33G_FIFOH, buf, WRD_COUNT); | ||
682 | buf += WRD_COUNT; | ||
683 | count -= WRD_COUNT; | ||
684 | } | ||
685 | else | ||
686 | { | ||
687 | insw(E33G_FIFOH, buf, count); | ||
688 | break; | ||
689 | } | ||
690 | } | ||
691 | blocked:; | ||
692 | outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL); | ||
693 | } | ||
694 | |||
695 | |||
696 | static void netdev_get_drvinfo(struct net_device *dev, | ||
697 | struct ethtool_drvinfo *info) | ||
698 | { | ||
699 | strcpy(info->driver, DRV_NAME); | ||
700 | strcpy(info->version, DRV_VERSION); | ||
701 | sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr); | ||
702 | } | ||
703 | |||
704 | static const struct ethtool_ops netdev_ethtool_ops = { | ||
705 | .get_drvinfo = netdev_get_drvinfo, | ||
706 | }; | ||
707 | |||
708 | #ifdef MODULE | ||
709 | #define MAX_EL2_CARDS 4 /* Max number of EL2 cards per module */ | ||
710 | |||
711 | static struct net_device *dev_el2[MAX_EL2_CARDS]; | ||
712 | static int io[MAX_EL2_CARDS]; | ||
713 | static int irq[MAX_EL2_CARDS]; | ||
714 | static int xcvr[MAX_EL2_CARDS]; /* choose int. or ext. xcvr */ | ||
715 | module_param_array(io, int, NULL, 0); | ||
716 | module_param_array(irq, int, NULL, 0); | ||
717 | module_param_array(xcvr, int, NULL, 0); | ||
718 | MODULE_PARM_DESC(io, "I/O base address(es)"); | ||
719 | MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); | ||
720 | MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)"); | ||
721 | MODULE_DESCRIPTION("3Com ISA EtherLink II, II/16 (3c503, 3c503/16) driver"); | ||
722 | MODULE_LICENSE("GPL"); | ||
723 | |||
724 | /* This is set up so that only a single autoprobe takes place per call. | ||
725 | ISA device autoprobes on a running machine are not recommended. */ | ||
726 | int __init | ||
727 | init_module(void) | ||
728 | { | ||
729 | struct net_device *dev; | ||
730 | int this_dev, found = 0; | ||
731 | |||
732 | for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) { | ||
733 | if (io[this_dev] == 0) { | ||
734 | if (this_dev != 0) break; /* only autoprobe 1st one */ | ||
735 | pr_notice("3c503.c: Presently autoprobing (not recommended) for a single card.\n"); | ||
736 | } | ||
737 | dev = alloc_eip_netdev(); | ||
738 | if (!dev) | ||
739 | break; | ||
740 | dev->irq = irq[this_dev]; | ||
741 | dev->base_addr = io[this_dev]; | ||
742 | dev->mem_end = xcvr[this_dev]; /* low 4bits = xcvr sel. */ | ||
743 | if (do_el2_probe(dev) == 0) { | ||
744 | dev_el2[found++] = dev; | ||
745 | continue; | ||
746 | } | ||
747 | free_netdev(dev); | ||
748 | pr_warning("3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]); | ||
749 | break; | ||
750 | } | ||
751 | if (found) | ||
752 | return 0; | ||
753 | return -ENXIO; | ||
754 | } | ||
755 | |||
756 | static void cleanup_card(struct net_device *dev) | ||
757 | { | ||
758 | /* NB: el2_close() handles free_irq */ | ||
759 | release_region(dev->base_addr, EL2_IO_EXTENT); | ||
760 | if (ei_status.mem) | ||
761 | iounmap(ei_status.mem); | ||
762 | } | ||
763 | |||
764 | void __exit | ||
765 | cleanup_module(void) | ||
766 | { | ||
767 | int this_dev; | ||
768 | |||
769 | for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) { | ||
770 | struct net_device *dev = dev_el2[this_dev]; | ||
771 | if (dev) { | ||
772 | unregister_netdev(dev); | ||
773 | cleanup_card(dev); | ||
774 | free_netdev(dev); | ||
775 | } | ||
776 | } | ||
777 | } | ||
778 | #endif /* MODULE */ | ||
diff --git a/drivers/net/ethernet/8390/3c503.h b/drivers/net/ethernet/8390/3c503.h new file mode 100644 index 000000000000..e2367b82a2ec --- /dev/null +++ b/drivers/net/ethernet/8390/3c503.h | |||
@@ -0,0 +1,91 @@ | |||
1 | /* Definitions for the 3Com 3c503 Etherlink 2. */ | ||
2 | /* This file is distributed under the GPL. | ||
3 | Many of these names and comments are directly from the Crynwr packet | ||
4 | drivers, which are released under the GPL. */ | ||
5 | |||
6 | #define EL2H (dev->base_addr + 0x400) | ||
7 | #define EL2L (dev->base_addr) | ||
8 | |||
9 | /* Vendor unique hardware addr. prefix. 3Com has 2 because they ran | ||
10 | out of available addresses on the first one... */ | ||
11 | |||
12 | #define OLD_3COM_ID 0x02608c | ||
13 | #define NEW_3COM_ID 0x0020af | ||
14 | |||
15 | /* Shared memory management parameters. NB: The 8 bit cards have only | ||
16 | one bank (MB1) which serves both Tx and Rx packet space. The 16bit | ||
17 | cards have 2 banks, MB0 for Tx packets, and MB1 for Rx packets. | ||
18 | You choose which bank appears in the sh. mem window with EGACFR_MBSn */ | ||
19 | |||
20 | #define EL2_MB0_START_PG (0x00) /* EL2/16 Tx packets go in bank 0 */ | ||
21 | #define EL2_MB1_START_PG (0x20) /* First page of bank 1 */ | ||
22 | #define EL2_MB1_STOP_PG (0x40) /* Last page +1 of bank 1 */ | ||
23 | |||
24 | /* 3Com 3c503 ASIC registers */ | ||
25 | #define E33G_STARTPG (EL2H+0) /* Start page, matching EN0_STARTPG */ | ||
26 | #define E33G_STOPPG (EL2H+1) /* Stop page, must match EN0_STOPPG */ | ||
27 | #define E33G_DRQCNT (EL2H+2) /* DMA burst count */ | ||
28 | #define E33G_IOBASE (EL2H+3) /* Read of I/O base jumpers. */ | ||
29 | /* (non-useful, but it also appears at the end of EPROM space) */ | ||
30 | #define E33G_ROMBASE (EL2H+4) /* Read of memory base jumpers. */ | ||
31 | #define E33G_GACFR (EL2H+5) /* Config/setup bits for the ASIC GA */ | ||
32 | #define E33G_CNTRL (EL2H+6) /* Board's main control register */ | ||
33 | #define E33G_STATUS (EL2H+7) /* Status on completions. */ | ||
34 | #define E33G_IDCFR (EL2H+8) /* Interrupt/DMA config register */ | ||
35 | /* (Which IRQ to assert, DMA chan to use) */ | ||
36 | #define E33G_DMAAH (EL2H+9) /* High byte of DMA address reg */ | ||
37 | #define E33G_DMAAL (EL2H+10) /* Low byte of DMA address reg */ | ||
38 | /* "Vector pointer" - if this address matches a read, the EPROM (rather than | ||
39 | shared RAM) is mapped into memory space. */ | ||
40 | #define E33G_VP2 (EL2H+11) | ||
41 | #define E33G_VP1 (EL2H+12) | ||
42 | #define E33G_VP0 (EL2H+13) | ||
43 | #define E33G_FIFOH (EL2H+14) /* FIFO for programmed I/O moves */ | ||
44 | #define E33G_FIFOL (EL2H+15) /* ... low byte of above. */ | ||
45 | |||
46 | /* Bits in E33G_CNTRL register: */ | ||
47 | |||
48 | #define ECNTRL_RESET (0x01) /* Software reset of the ASIC and 8390 */ | ||
49 | #define ECNTRL_THIN (0x02) /* Onboard xcvr enable, AUI disable */ | ||
50 | #define ECNTRL_AUI (0x00) /* Onboard xcvr disable, AUI enable */ | ||
51 | #define ECNTRL_SAPROM (0x04) /* Map the station address prom */ | ||
52 | #define ECNTRL_DBLBFR (0x20) /* FIFO configuration bit */ | ||
53 | #define ECNTRL_OUTPUT (0x40) /* PC-to-3C503 direction if 1 */ | ||
54 | #define ECNTRL_INPUT (0x00) /* 3C503-to-PC direction if 0 */ | ||
55 | #define ECNTRL_START (0x80) /* Start the DMA logic */ | ||
56 | |||
57 | /* Bits in E33G_STATUS register: */ | ||
58 | |||
59 | #define ESTAT_DPRDY (0x80) /* Data port (of FIFO) ready */ | ||
60 | #define ESTAT_UFLW (0x40) /* Tried to read FIFO when it was empty */ | ||
61 | #define ESTAT_OFLW (0x20) /* Tried to write FIFO when it was full */ | ||
62 | #define ESTAT_DTC (0x10) /* Terminal Count from PC bus DMA logic */ | ||
63 | #define ESTAT_DIP (0x08) /* DMA In Progress */ | ||
64 | |||
65 | /* Bits in E33G_GACFR register: */ | ||
66 | |||
67 | #define EGACFR_NIM (0x80) /* NIC interrupt mask */ | ||
68 | #define EGACFR_TCM (0x40) /* DMA term. count interrupt mask */ | ||
69 | #define EGACFR_RSEL (0x08) /* Map a bank of card mem into system mem */ | ||
70 | #define EGACFR_MBS2 (0x04) /* Memory bank select, bit 2. */ | ||
71 | #define EGACFR_MBS1 (0x02) /* Memory bank select, bit 1. */ | ||
72 | #define EGACFR_MBS0 (0x01) /* Memory bank select, bit 0. */ | ||
73 | |||
74 | #define EGACFR_NORM (0x49) /* TCM | RSEL | MBS0 */ | ||
75 | #define EGACFR_IRQOFF (0xc9) /* TCM | RSEL | MBS0 | NIM */ | ||
76 | |||
77 | /* | ||
78 | MBS2 MBS1 MBS0 Sh. mem windows card mem at: | ||
79 | ---- ---- ---- ----------------------------- | ||
80 | 0 0 0 0x0000 -- bank 0 | ||
81 | 0 0 1 0x2000 -- bank 1 (only choice for 8bit card) | ||
82 | 0 1 0 0x4000 -- bank 2, not used | ||
83 | 0 1 1 0x6000 -- bank 3, not used | ||
84 | |||
85 | There was going to be a 32k card that used bank 2 and 3, but it | ||
86 | never got produced. | ||
87 | |||
88 | */ | ||
89 | |||
90 | |||
91 | /* End of 3C503 parameter definitions */ | ||
diff --git a/drivers/net/ethernet/8390/8390.c b/drivers/net/ethernet/8390/8390.c new file mode 100644 index 000000000000..7c7518be1756 --- /dev/null +++ b/drivers/net/ethernet/8390/8390.c | |||
@@ -0,0 +1,103 @@ | |||
1 | /* 8390 core for usual drivers */ | ||
2 | |||
3 | static const char version[] = | ||
4 | "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; | ||
5 | |||
6 | #include "lib8390.c" | ||
7 | |||
8 | int ei_open(struct net_device *dev) | ||
9 | { | ||
10 | return __ei_open(dev); | ||
11 | } | ||
12 | EXPORT_SYMBOL(ei_open); | ||
13 | |||
14 | int ei_close(struct net_device *dev) | ||
15 | { | ||
16 | return __ei_close(dev); | ||
17 | } | ||
18 | EXPORT_SYMBOL(ei_close); | ||
19 | |||
20 | netdev_tx_t ei_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
21 | { | ||
22 | return __ei_start_xmit(skb, dev); | ||
23 | } | ||
24 | EXPORT_SYMBOL(ei_start_xmit); | ||
25 | |||
26 | struct net_device_stats *ei_get_stats(struct net_device *dev) | ||
27 | { | ||
28 | return __ei_get_stats(dev); | ||
29 | } | ||
30 | EXPORT_SYMBOL(ei_get_stats); | ||
31 | |||
32 | void ei_set_multicast_list(struct net_device *dev) | ||
33 | { | ||
34 | __ei_set_multicast_list(dev); | ||
35 | } | ||
36 | EXPORT_SYMBOL(ei_set_multicast_list); | ||
37 | |||
38 | void ei_tx_timeout(struct net_device *dev) | ||
39 | { | ||
40 | __ei_tx_timeout(dev); | ||
41 | } | ||
42 | EXPORT_SYMBOL(ei_tx_timeout); | ||
43 | |||
44 | irqreturn_t ei_interrupt(int irq, void *dev_id) | ||
45 | { | ||
46 | return __ei_interrupt(irq, dev_id); | ||
47 | } | ||
48 | EXPORT_SYMBOL(ei_interrupt); | ||
49 | |||
50 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
51 | void ei_poll(struct net_device *dev) | ||
52 | { | ||
53 | __ei_poll(dev); | ||
54 | } | ||
55 | EXPORT_SYMBOL(ei_poll); | ||
56 | #endif | ||
57 | |||
58 | const struct net_device_ops ei_netdev_ops = { | ||
59 | .ndo_open = ei_open, | ||
60 | .ndo_stop = ei_close, | ||
61 | .ndo_start_xmit = ei_start_xmit, | ||
62 | .ndo_tx_timeout = ei_tx_timeout, | ||
63 | .ndo_get_stats = ei_get_stats, | ||
64 | .ndo_set_multicast_list = ei_set_multicast_list, | ||
65 | .ndo_validate_addr = eth_validate_addr, | ||
66 | .ndo_set_mac_address = eth_mac_addr, | ||
67 | .ndo_change_mtu = eth_change_mtu, | ||
68 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
69 | .ndo_poll_controller = ei_poll, | ||
70 | #endif | ||
71 | }; | ||
72 | EXPORT_SYMBOL(ei_netdev_ops); | ||
73 | |||
74 | struct net_device *__alloc_ei_netdev(int size) | ||
75 | { | ||
76 | struct net_device *dev = ____alloc_ei_netdev(size); | ||
77 | if (dev) | ||
78 | dev->netdev_ops = &ei_netdev_ops; | ||
79 | return dev; | ||
80 | } | ||
81 | EXPORT_SYMBOL(__alloc_ei_netdev); | ||
82 | |||
83 | void NS8390_init(struct net_device *dev, int startp) | ||
84 | { | ||
85 | __NS8390_init(dev, startp); | ||
86 | } | ||
87 | EXPORT_SYMBOL(NS8390_init); | ||
88 | |||
89 | #if defined(MODULE) | ||
90 | |||
91 | static int __init ns8390_module_init(void) | ||
92 | { | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static void __exit ns8390_module_exit(void) | ||
97 | { | ||
98 | } | ||
99 | |||
100 | module_init(ns8390_module_init); | ||
101 | module_exit(ns8390_module_exit); | ||
102 | #endif /* MODULE */ | ||
103 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/ethernet/8390/8390.h b/drivers/net/ethernet/8390/8390.h new file mode 100644 index 000000000000..58a12e4c78f9 --- /dev/null +++ b/drivers/net/ethernet/8390/8390.h | |||
@@ -0,0 +1,232 @@ | |||
1 | /* Generic NS8390 register definitions. */ | ||
2 | /* This file is part of Donald Becker's 8390 drivers, and is distributed | ||
3 | under the same license. Auto-loading of 8390.o only in v2.2 - Paul G. | ||
4 | Some of these names and comments originated from the Crynwr | ||
5 | packet drivers, which are distributed under the GPL. */ | ||
6 | |||
7 | #ifndef _8390_h | ||
8 | #define _8390_h | ||
9 | |||
10 | #include <linux/if_ether.h> | ||
11 | #include <linux/ioport.h> | ||
12 | #include <linux/irqreturn.h> | ||
13 | #include <linux/skbuff.h> | ||
14 | |||
15 | #define TX_PAGES 12 /* Two Tx slots */ | ||
16 | |||
17 | #define ETHER_ADDR_LEN 6 | ||
18 | |||
19 | /* The 8390 specific per-packet-header format. */ | ||
20 | struct e8390_pkt_hdr { | ||
21 | unsigned char status; /* status */ | ||
22 | unsigned char next; /* pointer to next packet. */ | ||
23 | unsigned short count; /* header + packet length in bytes */ | ||
24 | }; | ||
25 | |||
26 | #ifdef notdef | ||
27 | extern int ei_debug; | ||
28 | #else | ||
29 | #define ei_debug 1 | ||
30 | #endif | ||
31 | |||
32 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
33 | extern void ei_poll(struct net_device *dev); | ||
34 | extern void eip_poll(struct net_device *dev); | ||
35 | #endif | ||
36 | |||
37 | |||
38 | /* Without I/O delay - non ISA or later chips */ | ||
39 | extern void NS8390_init(struct net_device *dev, int startp); | ||
40 | extern int ei_open(struct net_device *dev); | ||
41 | extern int ei_close(struct net_device *dev); | ||
42 | extern irqreturn_t ei_interrupt(int irq, void *dev_id); | ||
43 | extern void ei_tx_timeout(struct net_device *dev); | ||
44 | extern netdev_tx_t ei_start_xmit(struct sk_buff *skb, struct net_device *dev); | ||
45 | extern void ei_set_multicast_list(struct net_device *dev); | ||
46 | extern struct net_device_stats *ei_get_stats(struct net_device *dev); | ||
47 | |||
48 | extern const struct net_device_ops ei_netdev_ops; | ||
49 | |||
50 | extern struct net_device *__alloc_ei_netdev(int size); | ||
51 | static inline struct net_device *alloc_ei_netdev(void) | ||
52 | { | ||
53 | return __alloc_ei_netdev(0); | ||
54 | } | ||
55 | |||
56 | /* With I/O delay form */ | ||
57 | extern void NS8390p_init(struct net_device *dev, int startp); | ||
58 | extern int eip_open(struct net_device *dev); | ||
59 | extern int eip_close(struct net_device *dev); | ||
60 | extern irqreturn_t eip_interrupt(int irq, void *dev_id); | ||
61 | extern void eip_tx_timeout(struct net_device *dev); | ||
62 | extern netdev_tx_t eip_start_xmit(struct sk_buff *skb, struct net_device *dev); | ||
63 | extern void eip_set_multicast_list(struct net_device *dev); | ||
64 | extern struct net_device_stats *eip_get_stats(struct net_device *dev); | ||
65 | |||
66 | extern const struct net_device_ops eip_netdev_ops; | ||
67 | |||
68 | extern struct net_device *__alloc_eip_netdev(int size); | ||
69 | static inline struct net_device *alloc_eip_netdev(void) | ||
70 | { | ||
71 | return __alloc_eip_netdev(0); | ||
72 | } | ||
73 | |||
74 | /* You have one of these per-board */ | ||
75 | struct ei_device { | ||
76 | const char *name; | ||
77 | void (*reset_8390)(struct net_device *); | ||
78 | void (*get_8390_hdr)(struct net_device *, struct e8390_pkt_hdr *, int); | ||
79 | void (*block_output)(struct net_device *, int, const unsigned char *, int); | ||
80 | void (*block_input)(struct net_device *, int, struct sk_buff *, int); | ||
81 | unsigned long rmem_start; | ||
82 | unsigned long rmem_end; | ||
83 | void __iomem *mem; | ||
84 | unsigned char mcfilter[8]; | ||
85 | unsigned open:1; | ||
86 | unsigned word16:1; /* We have the 16-bit (vs 8-bit) version of the card. */ | ||
87 | unsigned bigendian:1; /* 16-bit big endian mode. Do NOT */ | ||
88 | /* set this on random 8390 clones! */ | ||
89 | unsigned txing:1; /* Transmit Active */ | ||
90 | unsigned irqlock:1; /* 8390's intrs disabled when '1'. */ | ||
91 | unsigned dmaing:1; /* Remote DMA Active */ | ||
92 | unsigned char tx_start_page, rx_start_page, stop_page; | ||
93 | unsigned char current_page; /* Read pointer in buffer */ | ||
94 | unsigned char interface_num; /* Net port (AUI, 10bT.) to use. */ | ||
95 | unsigned char txqueue; /* Tx Packet buffer queue length. */ | ||
96 | short tx1, tx2; /* Packet lengths for ping-pong tx. */ | ||
97 | short lasttx; /* Alpha version consistency check. */ | ||
98 | unsigned char reg0; /* Register '0' in a WD8013 */ | ||
99 | unsigned char reg5; /* Register '5' in a WD8013 */ | ||
100 | unsigned char saved_irq; /* Original dev->irq value. */ | ||
101 | u32 *reg_offset; /* Register mapping table */ | ||
102 | spinlock_t page_lock; /* Page register locks */ | ||
103 | unsigned long priv; /* Private field to store bus IDs etc. */ | ||
104 | #ifdef AX88796_PLATFORM | ||
105 | unsigned char rxcr_base; /* default value for RXCR */ | ||
106 | #endif | ||
107 | }; | ||
108 | |||
109 | /* The maximum number of 8390 interrupt service routines called per IRQ. */ | ||
110 | #define MAX_SERVICE 12 | ||
111 | |||
112 | /* The maximum time waited (in jiffies) before assuming a Tx failed. (20ms) */ | ||
113 | #define TX_TIMEOUT (20*HZ/100) | ||
114 | |||
115 | #define ei_status (*(struct ei_device *)netdev_priv(dev)) | ||
116 | |||
117 | /* Some generic ethernet register configurations. */ | ||
118 | #define E8390_TX_IRQ_MASK 0xa /* For register EN0_ISR */ | ||
119 | #define E8390_RX_IRQ_MASK 0x5 | ||
120 | |||
121 | #ifdef AX88796_PLATFORM | ||
122 | #define E8390_RXCONFIG (ei_status.rxcr_base | 0x04) | ||
123 | #define E8390_RXOFF (ei_status.rxcr_base | 0x20) | ||
124 | #else | ||
125 | #define E8390_RXCONFIG 0x4 /* EN0_RXCR: broadcasts, no multicast,errors */ | ||
126 | #define E8390_RXOFF 0x20 /* EN0_RXCR: Accept no packets */ | ||
127 | #endif | ||
128 | |||
129 | #define E8390_TXCONFIG 0x00 /* EN0_TXCR: Normal transmit mode */ | ||
130 | #define E8390_TXOFF 0x02 /* EN0_TXCR: Transmitter off */ | ||
131 | |||
132 | |||
133 | /* Register accessed at EN_CMD, the 8390 base addr. */ | ||
134 | #define E8390_STOP 0x01 /* Stop and reset the chip */ | ||
135 | #define E8390_START 0x02 /* Start the chip, clear reset */ | ||
136 | #define E8390_TRANS 0x04 /* Transmit a frame */ | ||
137 | #define E8390_RREAD 0x08 /* Remote read */ | ||
138 | #define E8390_RWRITE 0x10 /* Remote write */ | ||
139 | #define E8390_NODMA 0x20 /* Remote DMA */ | ||
140 | #define E8390_PAGE0 0x00 /* Select page chip registers */ | ||
141 | #define E8390_PAGE1 0x40 /* using the two high-order bits */ | ||
142 | #define E8390_PAGE2 0x80 /* Page 3 is invalid. */ | ||
143 | |||
144 | /* | ||
145 | * Only generate indirect loads given a machine that needs them. | ||
146 | * - removed AMIGA_PCMCIA from this list, handled as ISA io now | ||
147 | * - the _p for generates no delay by default 8390p.c overrides this. | ||
148 | */ | ||
149 | |||
150 | #ifndef ei_inb | ||
151 | #define ei_inb(_p) inb(_p) | ||
152 | #define ei_outb(_v,_p) outb(_v,_p) | ||
153 | #define ei_inb_p(_p) inb(_p) | ||
154 | #define ei_outb_p(_v,_p) outb(_v,_p) | ||
155 | #endif | ||
156 | |||
157 | #ifndef EI_SHIFT | ||
158 | #define EI_SHIFT(x) (x) | ||
159 | #endif | ||
160 | |||
161 | #define E8390_CMD EI_SHIFT(0x00) /* The command register (for all pages) */ | ||
162 | /* Page 0 register offsets. */ | ||
163 | #define EN0_CLDALO EI_SHIFT(0x01) /* Low byte of current local dma addr RD */ | ||
164 | #define EN0_STARTPG EI_SHIFT(0x01) /* Starting page of ring bfr WR */ | ||
165 | #define EN0_CLDAHI EI_SHIFT(0x02) /* High byte of current local dma addr RD */ | ||
166 | #define EN0_STOPPG EI_SHIFT(0x02) /* Ending page +1 of ring bfr WR */ | ||
167 | #define EN0_BOUNDARY EI_SHIFT(0x03) /* Boundary page of ring bfr RD WR */ | ||
168 | #define EN0_TSR EI_SHIFT(0x04) /* Transmit status reg RD */ | ||
169 | #define EN0_TPSR EI_SHIFT(0x04) /* Transmit starting page WR */ | ||
170 | #define EN0_NCR EI_SHIFT(0x05) /* Number of collision reg RD */ | ||
171 | #define EN0_TCNTLO EI_SHIFT(0x05) /* Low byte of tx byte count WR */ | ||
172 | #define EN0_FIFO EI_SHIFT(0x06) /* FIFO RD */ | ||
173 | #define EN0_TCNTHI EI_SHIFT(0x06) /* High byte of tx byte count WR */ | ||
174 | #define EN0_ISR EI_SHIFT(0x07) /* Interrupt status reg RD WR */ | ||
175 | #define EN0_CRDALO EI_SHIFT(0x08) /* low byte of current remote dma address RD */ | ||
176 | #define EN0_RSARLO EI_SHIFT(0x08) /* Remote start address reg 0 */ | ||
177 | #define EN0_CRDAHI EI_SHIFT(0x09) /* high byte, current remote dma address RD */ | ||
178 | #define EN0_RSARHI EI_SHIFT(0x09) /* Remote start address reg 1 */ | ||
179 | #define EN0_RCNTLO EI_SHIFT(0x0a) /* Remote byte count reg WR */ | ||
180 | #define EN0_RCNTHI EI_SHIFT(0x0b) /* Remote byte count reg WR */ | ||
181 | #define EN0_RSR EI_SHIFT(0x0c) /* rx status reg RD */ | ||
182 | #define EN0_RXCR EI_SHIFT(0x0c) /* RX configuration reg WR */ | ||
183 | #define EN0_TXCR EI_SHIFT(0x0d) /* TX configuration reg WR */ | ||
184 | #define EN0_COUNTER0 EI_SHIFT(0x0d) /* Rcv alignment error counter RD */ | ||
185 | #define EN0_DCFG EI_SHIFT(0x0e) /* Data configuration reg WR */ | ||
186 | #define EN0_COUNTER1 EI_SHIFT(0x0e) /* Rcv CRC error counter RD */ | ||
187 | #define EN0_IMR EI_SHIFT(0x0f) /* Interrupt mask reg WR */ | ||
188 | #define EN0_COUNTER2 EI_SHIFT(0x0f) /* Rcv missed frame error counter RD */ | ||
189 | |||
190 | /* Bits in EN0_ISR - Interrupt status register */ | ||
191 | #define ENISR_RX 0x01 /* Receiver, no error */ | ||
192 | #define ENISR_TX 0x02 /* Transmitter, no error */ | ||
193 | #define ENISR_RX_ERR 0x04 /* Receiver, with error */ | ||
194 | #define ENISR_TX_ERR 0x08 /* Transmitter, with error */ | ||
195 | #define ENISR_OVER 0x10 /* Receiver overwrote the ring */ | ||
196 | #define ENISR_COUNTERS 0x20 /* Counters need emptying */ | ||
197 | #define ENISR_RDC 0x40 /* remote dma complete */ | ||
198 | #define ENISR_RESET 0x80 /* Reset completed */ | ||
199 | #define ENISR_ALL 0x3f /* Interrupts we will enable */ | ||
200 | |||
201 | /* Bits in EN0_DCFG - Data config register */ | ||
202 | #define ENDCFG_WTS 0x01 /* word transfer mode selection */ | ||
203 | #define ENDCFG_BOS 0x02 /* byte order selection */ | ||
204 | |||
205 | /* Page 1 register offsets. */ | ||
206 | #define EN1_PHYS EI_SHIFT(0x01) /* This board's physical enet addr RD WR */ | ||
207 | #define EN1_PHYS_SHIFT(i) EI_SHIFT(i+1) /* Get and set mac address */ | ||
208 | #define EN1_CURPAG EI_SHIFT(0x07) /* Current memory page RD WR */ | ||
209 | #define EN1_MULT EI_SHIFT(0x08) /* Multicast filter mask array (8 bytes) RD WR */ | ||
210 | #define EN1_MULT_SHIFT(i) EI_SHIFT(8+i) /* Get and set multicast filter */ | ||
211 | |||
212 | /* Bits in received packet status byte and EN0_RSR*/ | ||
213 | #define ENRSR_RXOK 0x01 /* Received a good packet */ | ||
214 | #define ENRSR_CRC 0x02 /* CRC error */ | ||
215 | #define ENRSR_FAE 0x04 /* frame alignment error */ | ||
216 | #define ENRSR_FO 0x08 /* FIFO overrun */ | ||
217 | #define ENRSR_MPA 0x10 /* missed pkt */ | ||
218 | #define ENRSR_PHY 0x20 /* physical/multicast address */ | ||
219 | #define ENRSR_DIS 0x40 /* receiver disable. set in monitor mode */ | ||
220 | #define ENRSR_DEF 0x80 /* deferring */ | ||
221 | |||
222 | /* Transmitted packet status, EN0_TSR. */ | ||
223 | #define ENTSR_PTX 0x01 /* Packet transmitted without error */ | ||
224 | #define ENTSR_ND 0x02 /* The transmit wasn't deferred. */ | ||
225 | #define ENTSR_COL 0x04 /* The transmit collided at least once. */ | ||
226 | #define ENTSR_ABT 0x08 /* The transmit collided 16 times, and was deferred. */ | ||
227 | #define ENTSR_CRS 0x10 /* The carrier sense was lost. */ | ||
228 | #define ENTSR_FU 0x20 /* A "FIFO underrun" occurred during transmit. */ | ||
229 | #define ENTSR_CDH 0x40 /* The collision detect "heartbeat" signal was lost. */ | ||
230 | #define ENTSR_OWC 0x80 /* There was an out-of-window collision. */ | ||
231 | |||
232 | #endif /* _8390_h */ | ||
diff --git a/drivers/net/ethernet/8390/8390p.c b/drivers/net/ethernet/8390/8390p.c new file mode 100644 index 000000000000..a2a64ea0b691 --- /dev/null +++ b/drivers/net/ethernet/8390/8390p.c | |||
@@ -0,0 +1,105 @@ | |||
1 | /* 8390 core for ISA devices needing bus delays */ | ||
2 | |||
3 | static const char version[] = | ||
4 | "8390p.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; | ||
5 | |||
6 | #define ei_inb(_p) inb(_p) | ||
7 | #define ei_outb(_v, _p) outb(_v, _p) | ||
8 | #define ei_inb_p(_p) inb_p(_p) | ||
9 | #define ei_outb_p(_v, _p) outb_p(_v, _p) | ||
10 | |||
11 | #include "lib8390.c" | ||
12 | |||
13 | int eip_open(struct net_device *dev) | ||
14 | { | ||
15 | return __ei_open(dev); | ||
16 | } | ||
17 | EXPORT_SYMBOL(eip_open); | ||
18 | |||
19 | int eip_close(struct net_device *dev) | ||
20 | { | ||
21 | return __ei_close(dev); | ||
22 | } | ||
23 | EXPORT_SYMBOL(eip_close); | ||
24 | |||
25 | netdev_tx_t eip_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
26 | { | ||
27 | return __ei_start_xmit(skb, dev); | ||
28 | } | ||
29 | EXPORT_SYMBOL(eip_start_xmit); | ||
30 | |||
31 | struct net_device_stats *eip_get_stats(struct net_device *dev) | ||
32 | { | ||
33 | return __ei_get_stats(dev); | ||
34 | } | ||
35 | EXPORT_SYMBOL(eip_get_stats); | ||
36 | |||
37 | void eip_set_multicast_list(struct net_device *dev) | ||
38 | { | ||
39 | __ei_set_multicast_list(dev); | ||
40 | } | ||
41 | EXPORT_SYMBOL(eip_set_multicast_list); | ||
42 | |||
43 | void eip_tx_timeout(struct net_device *dev) | ||
44 | { | ||
45 | __ei_tx_timeout(dev); | ||
46 | } | ||
47 | EXPORT_SYMBOL(eip_tx_timeout); | ||
48 | |||
49 | irqreturn_t eip_interrupt(int irq, void *dev_id) | ||
50 | { | ||
51 | return __ei_interrupt(irq, dev_id); | ||
52 | } | ||
53 | EXPORT_SYMBOL(eip_interrupt); | ||
54 | |||
55 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
56 | void eip_poll(struct net_device *dev) | ||
57 | { | ||
58 | __ei_poll(dev); | ||
59 | } | ||
60 | EXPORT_SYMBOL(eip_poll); | ||
61 | #endif | ||
62 | |||
63 | const struct net_device_ops eip_netdev_ops = { | ||
64 | .ndo_open = eip_open, | ||
65 | .ndo_stop = eip_close, | ||
66 | .ndo_start_xmit = eip_start_xmit, | ||
67 | .ndo_tx_timeout = eip_tx_timeout, | ||
68 | .ndo_get_stats = eip_get_stats, | ||
69 | .ndo_set_multicast_list = eip_set_multicast_list, | ||
70 | .ndo_validate_addr = eth_validate_addr, | ||
71 | .ndo_set_mac_address = eth_mac_addr, | ||
72 | .ndo_change_mtu = eth_change_mtu, | ||
73 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
74 | .ndo_poll_controller = eip_poll, | ||
75 | #endif | ||
76 | }; | ||
77 | EXPORT_SYMBOL(eip_netdev_ops); | ||
78 | |||
79 | struct net_device *__alloc_eip_netdev(int size) | ||
80 | { | ||
81 | struct net_device *dev = ____alloc_ei_netdev(size); | ||
82 | if (dev) | ||
83 | dev->netdev_ops = &eip_netdev_ops; | ||
84 | return dev; | ||
85 | } | ||
86 | EXPORT_SYMBOL(__alloc_eip_netdev); | ||
87 | |||
88 | void NS8390p_init(struct net_device *dev, int startp) | ||
89 | { | ||
90 | __NS8390_init(dev, startp); | ||
91 | } | ||
92 | EXPORT_SYMBOL(NS8390p_init); | ||
93 | |||
94 | static int __init NS8390p_init_module(void) | ||
95 | { | ||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static void __exit NS8390p_cleanup_module(void) | ||
100 | { | ||
101 | } | ||
102 | |||
103 | module_init(NS8390p_init_module); | ||
104 | module_exit(NS8390p_cleanup_module); | ||
105 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/ethernet/8390/Kconfig b/drivers/net/ethernet/8390/Kconfig new file mode 100644 index 000000000000..5cd53f1b84d3 --- /dev/null +++ b/drivers/net/ethernet/8390/Kconfig | |||
@@ -0,0 +1,348 @@ | |||
1 | # | ||
2 | # 8390 device configuration | ||
3 | # | ||
4 | |||
5 | config NET_VENDOR_8390 | ||
6 | bool "National Semi-conductor 8390 devices" | ||
7 | depends on AMIGA_PCMCIA || PCI || SUPERH || ISA || MCA || EISA || \ | ||
8 | MAC || M32R || MACH_TX49XX || MCA_LEGACY || H8300 || \ | ||
9 | ARM || MIPS || ZORRO || PCMCIA || EXPERIMENTAL | ||
10 | ---help--- | ||
11 | If you have a network (Ethernet) card belonging to this class, say Y | ||
12 | and read the Ethernet-HOWTO, available from | ||
13 | <http://www.tldp.org/docs.html#howto>. | ||
14 | |||
15 | Note that the answer to this question doesn't directly affect the | ||
16 | kernel: saying N will just cause the configurator to skip all | ||
17 | the questions about Western Digital cards. If you say Y, you will be | ||
18 | asked for your specific card in the following questions. | ||
19 | |||
20 | if NET_VENDOR_8390 | ||
21 | |||
22 | config EL2 | ||
23 | tristate "3c503 \"EtherLink II\" support" | ||
24 | depends on ISA | ||
25 | select CRC32 | ||
26 | ---help--- | ||
27 | If you have a network (Ethernet) card of this type, say Y and read | ||
28 | the Ethernet-HOWTO, available from | ||
29 | <http://www.tldp.org/docs.html#howto>. | ||
30 | |||
31 | To compile this driver as a module, choose M here. The module | ||
32 | will be called 3c503. | ||
33 | |||
34 | config AC3200 | ||
35 | tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)" | ||
36 | depends on PCI && (ISA || EISA) && EXPERIMENTAL | ||
37 | select CRC32 | ||
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 ac3200. | ||
45 | |||
46 | config PCMCIA_AXNET | ||
47 | tristate "Asix AX88190 PCMCIA support" | ||
48 | depends on PCMCIA | ||
49 | ---help--- | ||
50 | Say Y here if you intend to attach an Asix AX88190-based PCMCIA | ||
51 | (PC-card) Fast Ethernet card to your computer. These cards are | ||
52 | nearly NE2000 compatible but need a separate driver due to a few | ||
53 | misfeatures. | ||
54 | |||
55 | To compile this driver as a module, choose M here: the module will be | ||
56 | called axnet_cs. If unsure, say N. | ||
57 | |||
58 | config AX88796 | ||
59 | tristate "ASIX AX88796 NE2000 clone support" | ||
60 | depends on (ARM || MIPS || SUPERH) | ||
61 | select PHYLIB | ||
62 | select MDIO_BITBANG | ||
63 | ---help--- | ||
64 | AX88796 driver, using platform bus to provide | ||
65 | chip detection and resources | ||
66 | |||
67 | config AX88796_93CX6 | ||
68 | bool "ASIX AX88796 external 93CX6 eeprom support" | ||
69 | depends on AX88796 | ||
70 | select EEPROM_93CX6 | ||
71 | ---help--- | ||
72 | Select this if your platform comes with an external 93CX6 eeprom. | ||
73 | |||
74 | config E2100 | ||
75 | tristate "Cabletron E21xx support" | ||
76 | depends on ISA | ||
77 | select CRC32 | ||
78 | ---help--- | ||
79 | If you have a network (Ethernet) card of this type, say Y and read | ||
80 | the Ethernet-HOWTO, available from | ||
81 | <http://www.tldp.org/docs.html#howto>. | ||
82 | |||
83 | To compile this driver as a module, choose M here. The module | ||
84 | will be called e2100. | ||
85 | |||
86 | config ES3210 | ||
87 | tristate "Racal-Interlan EISA ES3210 support (EXPERIMENTAL)" | ||
88 | depends on PCI && EISA && EXPERIMENTAL | ||
89 | select CRC32 | ||
90 | ---help--- | ||
91 | If you have a network (Ethernet) card of this type, say Y and read | ||
92 | the Ethernet-HOWTO, available from | ||
93 | <http://www.tldp.org/docs.html#howto>. | ||
94 | |||
95 | To compile this driver as a module, choose M here. The module | ||
96 | will be called es3210. | ||
97 | |||
98 | config HPLAN_PLUS | ||
99 | tristate "HP PCLAN+ (27247B and 27252A) support" | ||
100 | depends on ISA | ||
101 | select CRC32 | ||
102 | ---help--- | ||
103 | If you have a network (Ethernet) card of this type, say Y and read | ||
104 | the Ethernet-HOWTO, available from | ||
105 | <http://www.tldp.org/docs.html#howto>. | ||
106 | |||
107 | To compile this driver as a module, choose M here. The module | ||
108 | will be called hp-plus. | ||
109 | |||
110 | config HPLAN | ||
111 | tristate "HP PCLAN (27245 and other 27xxx series) support" | ||
112 | depends on ISA | ||
113 | select CRC32 | ||
114 | ---help--- | ||
115 | If you have a network (Ethernet) card of this type, say Y and read | ||
116 | the Ethernet-HOWTO, available from | ||
117 | <http://www.tldp.org/docs.html#howto>. | ||
118 | |||
119 | To compile this driver as a module, choose M here. The module | ||
120 | will be called hp. | ||
121 | |||
122 | config HYDRA | ||
123 | tristate "Hydra support" | ||
124 | depends on ZORRO | ||
125 | select CRC32 | ||
126 | ---help--- | ||
127 | If you have a Hydra Ethernet adapter, say Y. Otherwise, say N. | ||
128 | |||
129 | To compile this driver as a module, choose M here: the module | ||
130 | will be called hydra. | ||
131 | |||
132 | config ARM_ETHERH | ||
133 | tristate "I-cubed EtherH/ANT EtherM support" | ||
134 | depends on ARM && ARCH_ACORN | ||
135 | select CRC32 | ||
136 | ---help--- | ||
137 | If you have an Acorn system with one of these network cards, you | ||
138 | should say Y to this option if you wish to use it with Linux. | ||
139 | |||
140 | config LNE390 | ||
141 | tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)" | ||
142 | depends on PCI && EISA && EXPERIMENTAL | ||
143 | select CRC32 | ||
144 | ---help--- | ||
145 | If you have a network (Ethernet) card of this type, say Y and read | ||
146 | the Ethernet-HOWTO, available from | ||
147 | <http://www.tldp.org/docs.html#howto>. | ||
148 | |||
149 | To compile this driver as a module, choose M here. The module | ||
150 | will be called lne390. | ||
151 | |||
152 | config MAC8390 | ||
153 | bool "Macintosh NS 8390 based ethernet cards" | ||
154 | depends on MAC | ||
155 | select CRC32 | ||
156 | ---help--- | ||
157 | If you want to include a driver to support Nubus or LC-PDS | ||
158 | Ethernet cards using an NS8390 chipset or its equivalent, say Y | ||
159 | and read the Ethernet-HOWTO, available from | ||
160 | <http://www.tldp.org/docs.html#howto>. | ||
161 | |||
162 | config NE2000 | ||
163 | tristate "NE2000/NE1000 support" | ||
164 | depends on (ISA || (Q40 && m) || M32R || MACH_TX49XX) | ||
165 | select CRC32 | ||
166 | ---help--- | ||
167 | If you have a network (Ethernet) card of this type, say Y and read | ||
168 | the Ethernet-HOWTO, available from | ||
169 | <http://www.tldp.org/docs.html#howto>. Many Ethernet cards | ||
170 | without a specific driver are compatible with NE2000. | ||
171 | |||
172 | If you have a PCI NE2000 card however, say N here and Y to "PCI | ||
173 | NE2000 and clone support" under "EISA, VLB, PCI and on board | ||
174 | controllers" below. If you have a NE2000 card and are running on | ||
175 | an MCA system (a bus system used on some IBM PS/2 computers and | ||
176 | laptops), say N here and Y to "NE/2 (ne2000 MCA version) support", | ||
177 | below. | ||
178 | |||
179 | To compile this driver as a module, choose M here. The module | ||
180 | will be called ne. | ||
181 | |||
182 | config NE2_MCA | ||
183 | tristate "NE/2 (ne2000 MCA version) support" | ||
184 | depends on MCA_LEGACY | ||
185 | select CRC32 | ||
186 | ---help--- | ||
187 | If you have a network (Ethernet) card of this type, say Y and read | ||
188 | the Ethernet-HOWTO, available from | ||
189 | <http://www.tldp.org/docs.html#howto>. | ||
190 | |||
191 | To compile this driver as a module, choose M here. The module | ||
192 | will be called ne2. | ||
193 | |||
194 | config NE2K_PCI | ||
195 | tristate "PCI NE2000 and clones support (see help)" | ||
196 | depends on PCI | ||
197 | select CRC32 | ||
198 | ---help--- | ||
199 | This driver is for NE2000 compatible PCI cards. It will not work | ||
200 | with ISA NE2000 cards (they have their own driver, "NE2000/NE1000 | ||
201 | support" below). If you have a PCI NE2000 network (Ethernet) card, | ||
202 | say Y and read the Ethernet-HOWTO, available from | ||
203 | <http://www.tldp.org/docs.html#howto>. | ||
204 | |||
205 | This driver also works for the following NE2000 clone cards: | ||
206 | RealTek RTL-8029 Winbond 89C940 Compex RL2000 KTI ET32P2 | ||
207 | NetVin NV5000SC Via 86C926 SureCom NE34 Winbond | ||
208 | Holtek HT80232 Holtek HT80229 | ||
209 | |||
210 | To compile this driver as a module, choose M here. The module | ||
211 | will be called ne2k-pci. | ||
212 | |||
213 | config APNE | ||
214 | tristate "PCMCIA NE2000 support" | ||
215 | depends on AMIGA_PCMCIA | ||
216 | select CRC32 | ||
217 | ---help--- | ||
218 | If you have a PCMCIA NE2000 compatible adapter, say Y. Otherwise, | ||
219 | say N. | ||
220 | |||
221 | To compile this driver as a module, choose M here: the module | ||
222 | will be called apne. | ||
223 | |||
224 | config NE3210 | ||
225 | tristate "Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)" | ||
226 | depends on PCI && EISA && EXPERIMENTAL | ||
227 | select CRC32 | ||
228 | ---help--- | ||
229 | If you have a network (Ethernet) card of this type, say Y and read | ||
230 | the Ethernet-HOWTO, available from | ||
231 | <http://www.tldp.org/docs.html#howto>. Note that this driver | ||
232 | will NOT WORK for NE3200 cards as they are completely different. | ||
233 | |||
234 | To compile this driver as a module, choose M here. The module | ||
235 | will be called ne3210. | ||
236 | |||
237 | config PCMCIA_PCNET | ||
238 | tristate "NE2000 compatible PCMCIA support" | ||
239 | depends on PCMCIA | ||
240 | select CRC32 | ||
241 | ---help--- | ||
242 | Say Y here if you intend to attach an NE2000 compatible PCMCIA | ||
243 | (PC-card) Ethernet or Fast Ethernet card to your computer. | ||
244 | |||
245 | To compile this driver as a module, choose M here: the module will be | ||
246 | called pcnet_cs. If unsure, say N. | ||
247 | |||
248 | config NE_H8300 | ||
249 | tristate "NE2000 compatible support for H8/300" | ||
250 | depends on H8300 | ||
251 | ---help--- | ||
252 | Say Y here if you want to use the NE2000 compatible | ||
253 | controller on the Renesas H8/300 processor. | ||
254 | |||
255 | config STNIC | ||
256 | tristate "National DP83902AV support" | ||
257 | depends on SUPERH | ||
258 | select CRC32 | ||
259 | ---help--- | ||
260 | Support for cards based on the National Semiconductor DP83902AV | ||
261 | ST-NIC Serial Network Interface Controller for Twisted Pair. This | ||
262 | is a 10Mbit/sec Ethernet controller. Product overview and specs at | ||
263 | <http://www.national.com/pf/DP/DP83902A.html>. | ||
264 | |||
265 | If unsure, say N. | ||
266 | |||
267 | config NET_VENDOR_SMC | ||
268 | bool "Western Digital/SMC cards" | ||
269 | depends on (ISA || MCA || EISA || MAC) | ||
270 | ---help--- | ||
271 | If you have a network (Ethernet) card belonging to this class, say Y | ||
272 | and read the Ethernet-HOWTO, available from | ||
273 | <http://www.tldp.org/docs.html#howto>. | ||
274 | |||
275 | Note that the answer to this question doesn't directly affect the | ||
276 | kernel: saying N will just cause the configurator to skip all | ||
277 | the questions about Western Digital cards. If you say Y, you will be | ||
278 | asked for your specific card in the following questions. | ||
279 | |||
280 | config ULTRAMCA | ||
281 | tristate "SMC Ultra MCA support" | ||
282 | depends on NET_VENDOR_SMC && MCA | ||
283 | select CRC32 | ||
284 | ---help--- | ||
285 | If you have a network (Ethernet) card of this type and are running | ||
286 | an MCA based system (PS/2), say Y and read the Ethernet-HOWTO, | ||
287 | available from <http://www.tldp.org/docs.html#howto>. | ||
288 | |||
289 | To compile this driver as a module, choose M here. The module | ||
290 | will be called smc-mca. | ||
291 | |||
292 | config ULTRA | ||
293 | tristate "SMC Ultra support" | ||
294 | depends on NET_VENDOR_SMC && ISA | ||
295 | select CRC32 | ||
296 | ---help--- | ||
297 | If you have a network (Ethernet) card of this type, say Y and read | ||
298 | the Ethernet-HOWTO, available from | ||
299 | <http://www.tldp.org/docs.html#howto>. | ||
300 | |||
301 | Important: There have been many reports that, with some motherboards | ||
302 | mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible, | ||
303 | such as some BusLogic models) causes corruption problems with many | ||
304 | operating systems. The Linux smc-ultra driver has a work-around for | ||
305 | this but keep it in mind if you have such a SCSI card and have | ||
306 | problems. | ||
307 | |||
308 | To compile this driver as a module, choose M here. The module | ||
309 | will be called smc-ultra. | ||
310 | |||
311 | config ULTRA32 | ||
312 | tristate "SMC Ultra32 EISA support" | ||
313 | depends on NET_VENDOR_SMC && EISA | ||
314 | select CRC32 | ||
315 | ---help--- | ||
316 | If you have a network (Ethernet) card of this type, say Y and read | ||
317 | the Ethernet-HOWTO, available from | ||
318 | <http://www.tldp.org/docs.html#howto>. | ||
319 | |||
320 | To compile this driver as a module, choose M here. The module | ||
321 | will be called smc-ultra32. | ||
322 | |||
323 | config WD80x3 | ||
324 | tristate "WD80*3 support" | ||
325 | depends on NET_VENDOR_SMC && ISA | ||
326 | select CRC32 | ||
327 | ---help--- | ||
328 | If you have a network (Ethernet) card of this type, say Y and read | ||
329 | the Ethernet-HOWTO, available from | ||
330 | <http://www.tldp.org/docs.html#howto>. | ||
331 | |||
332 | To compile this driver as a module, choose M here. The module | ||
333 | will be called wd. | ||
334 | |||
335 | config ZORRO8390 | ||
336 | tristate "Zorro NS8390-based Ethernet support" | ||
337 | depends on ZORRO | ||
338 | select CRC32 | ||
339 | ---help--- | ||
340 | This driver is for Zorro Ethernet cards using an NS8390-compatible | ||
341 | chipset, like the Village Tronic Ariadne II and the Individual | ||
342 | Computers X-Surf Ethernet cards. If you have such a card, say Y. | ||
343 | Otherwise, say N. | ||
344 | |||
345 | To compile this driver as a module, choose M here: the module | ||
346 | will be called zorro8390. | ||
347 | |||
348 | endif # NET_VENDOR_8390 | ||
diff --git a/drivers/net/ethernet/8390/Makefile b/drivers/net/ethernet/8390/Makefile new file mode 100644 index 000000000000..3337d7fb4344 --- /dev/null +++ b/drivers/net/ethernet/8390/Makefile | |||
@@ -0,0 +1,29 @@ | |||
1 | # | ||
2 | # Makefile for the 8390 network device drivers. | ||
3 | # | ||
4 | |||
5 | obj-$(CONFIG_MAC8390) += mac8390.o | ||
6 | obj-$(CONFIG_AC3200) += ac3200.o 8390.o | ||
7 | obj-$(CONFIG_APNE) += apne.o 8390.o | ||
8 | obj-$(CONFIG_ARM_ETHERH) += etherh.o | ||
9 | obj-$(CONFIG_AX88796) += ax88796.o | ||
10 | obj-$(CONFIG_E2100) += e2100.o 8390.o | ||
11 | obj-$(CONFIG_EL2) += 3c503.o 8390p.o | ||
12 | obj-$(CONFIG_ES3210) += es3210.o 8390.o | ||
13 | obj-$(CONFIG_HPLAN_PLUS) += hp-plus.o 8390p.o | ||
14 | obj-$(CONFIG_HPLAN) += hp.o 8390p.o | ||
15 | obj-$(CONFIG_HYDRA) += hydra.o 8390.o | ||
16 | obj-$(CONFIG_LNE390) += lne390.o 8390.o | ||
17 | obj-$(CONFIG_NE2000) += ne.o 8390p.o | ||
18 | obj-$(CONFIG_NE2_MCA) += ne2.o 8390p.o | ||
19 | obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o | ||
20 | obj-$(CONFIG_NE3210) += ne3210.o 8390.o | ||
21 | obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o | ||
22 | obj-$(CONFIG_PCMCIA_AXNET) += axnet_cs.o 8390.o | ||
23 | obj-$(CONFIG_PCMCIA_PCNET) += pcnet_cs.o 8390.o | ||
24 | obj-$(CONFIG_STNIC) += stnic.o 8390.o | ||
25 | obj-$(CONFIG_ULTRA) += smc-ultra.o 8390.o | ||
26 | obj-$(CONFIG_ULTRA32) += smc-ultra32.o 8390.o | ||
27 | obj-$(CONFIG_ULTRAMCA) += smc-mca.o 8390.o | ||
28 | obj-$(CONFIG_WD80x3) += wd.o 8390.o | ||
29 | obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o | ||
diff --git a/drivers/net/ethernet/8390/ac3200.c b/drivers/net/ethernet/8390/ac3200.c new file mode 100644 index 000000000000..f07b2e980fbc --- /dev/null +++ b/drivers/net/ethernet/8390/ac3200.c | |||
@@ -0,0 +1,432 @@ | |||
1 | /* ac3200.c: A driver for the Ansel Communications EISA ethernet adaptor. */ | ||
2 | /* | ||
3 | Written 1993, 1994 by Donald Becker. | ||
4 | Copyright 1993 United States Government as represented by the Director, | ||
5 | National Security Agency. This software may only be used and distributed | ||
6 | according to the terms of the GNU General Public License as modified by SRC, | ||
7 | incorporated herein by reference. | ||
8 | |||
9 | The author may be reached as becker@scyld.com, or C/O | ||
10 | Scyld Computing Corporation | ||
11 | 410 Severn Ave., Suite 210 | ||
12 | Annapolis MD 21403 | ||
13 | |||
14 | This is driver for the Ansel Communications Model 3200 EISA Ethernet LAN | ||
15 | Adapter. The programming information is from the users manual, as related | ||
16 | by glee@ardnassak.math.clemson.edu. | ||
17 | |||
18 | Changelog: | ||
19 | |||
20 | Paul Gortmaker 05/98 : add support for shared mem above 1MB. | ||
21 | |||
22 | */ | ||
23 | |||
24 | static const char version[] = | ||
25 | "ac3200.c:v1.01 7/1/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/eisa.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/string.h> | ||
32 | #include <linux/netdevice.h> | ||
33 | #include <linux/etherdevice.h> | ||
34 | #include <linux/init.h> | ||
35 | #include <linux/interrupt.h> | ||
36 | |||
37 | #include <asm/system.h> | ||
38 | #include <asm/io.h> | ||
39 | #include <asm/irq.h> | ||
40 | |||
41 | #include "8390.h" | ||
42 | |||
43 | #define DRV_NAME "ac3200" | ||
44 | |||
45 | /* Offsets from the base address. */ | ||
46 | #define AC_NIC_BASE 0x00 | ||
47 | #define AC_SA_PROM 0x16 /* The station address PROM. */ | ||
48 | #define AC_ADDR0 0x00 /* Prefix station address values. */ | ||
49 | #define AC_ADDR1 0x40 | ||
50 | #define AC_ADDR2 0x90 | ||
51 | #define AC_ID_PORT 0xC80 | ||
52 | #define AC_EISA_ID 0x0110d305 | ||
53 | #define AC_RESET_PORT 0xC84 | ||
54 | #define AC_RESET 0x00 | ||
55 | #define AC_ENABLE 0x01 | ||
56 | #define AC_CONFIG 0xC90 /* The configuration port. */ | ||
57 | |||
58 | #define AC_IO_EXTENT 0x20 | ||
59 | /* Actually accessed is: | ||
60 | * AC_NIC_BASE (0-15) | ||
61 | * AC_SA_PROM (0-5) | ||
62 | * AC_ID_PORT (0-3) | ||
63 | * AC_RESET_PORT | ||
64 | * AC_CONFIG | ||
65 | */ | ||
66 | |||
67 | /* Decoding of the configuration register. */ | ||
68 | static unsigned char config2irqmap[8] __initdata = {15, 12, 11, 10, 9, 7, 5, 3}; | ||
69 | static int addrmap[8] = | ||
70 | {0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000, 0xD0000, 0 }; | ||
71 | static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"}; | ||
72 | |||
73 | #define config2irq(configval) config2irqmap[((configval) >> 3) & 7] | ||
74 | #define config2mem(configval) addrmap[(configval) & 7] | ||
75 | #define config2name(configval) port_name[((configval) >> 6) & 3] | ||
76 | |||
77 | /* First and last 8390 pages. */ | ||
78 | #define AC_START_PG 0x00 /* First page of 8390 TX buffer */ | ||
79 | #define AC_STOP_PG 0x80 /* Last page +1 of the 8390 RX ring */ | ||
80 | |||
81 | static int ac_probe1(int ioaddr, struct net_device *dev); | ||
82 | |||
83 | static int ac_open(struct net_device *dev); | ||
84 | static void ac_reset_8390(struct net_device *dev); | ||
85 | static void ac_block_input(struct net_device *dev, int count, | ||
86 | struct sk_buff *skb, int ring_offset); | ||
87 | static void ac_block_output(struct net_device *dev, const int count, | ||
88 | const unsigned char *buf, const int start_page); | ||
89 | static void ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
90 | int ring_page); | ||
91 | |||
92 | static int ac_close_card(struct net_device *dev); | ||
93 | |||
94 | |||
95 | /* Probe for the AC3200. | ||
96 | |||
97 | The AC3200 can be identified by either the EISA configuration registers, | ||
98 | or the unique value in the station address PROM. | ||
99 | */ | ||
100 | |||
101 | static int __init do_ac3200_probe(struct net_device *dev) | ||
102 | { | ||
103 | unsigned short ioaddr = dev->base_addr; | ||
104 | int irq = dev->irq; | ||
105 | int mem_start = dev->mem_start; | ||
106 | |||
107 | if (ioaddr > 0x1ff) /* Check a single specified location. */ | ||
108 | return ac_probe1(ioaddr, dev); | ||
109 | else if (ioaddr > 0) /* Don't probe at all. */ | ||
110 | return -ENXIO; | ||
111 | |||
112 | if ( ! EISA_bus) | ||
113 | return -ENXIO; | ||
114 | |||
115 | for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { | ||
116 | if (ac_probe1(ioaddr, dev) == 0) | ||
117 | return 0; | ||
118 | dev->irq = irq; | ||
119 | dev->mem_start = mem_start; | ||
120 | } | ||
121 | |||
122 | return -ENODEV; | ||
123 | } | ||
124 | |||
125 | #ifndef MODULE | ||
126 | struct net_device * __init ac3200_probe(int unit) | ||
127 | { | ||
128 | struct net_device *dev = alloc_ei_netdev(); | ||
129 | int err; | ||
130 | |||
131 | if (!dev) | ||
132 | return ERR_PTR(-ENOMEM); | ||
133 | |||
134 | sprintf(dev->name, "eth%d", unit); | ||
135 | netdev_boot_setup_check(dev); | ||
136 | |||
137 | err = do_ac3200_probe(dev); | ||
138 | if (err) | ||
139 | goto out; | ||
140 | return dev; | ||
141 | out: | ||
142 | free_netdev(dev); | ||
143 | return ERR_PTR(err); | ||
144 | } | ||
145 | #endif | ||
146 | |||
147 | static const struct net_device_ops ac_netdev_ops = { | ||
148 | .ndo_open = ac_open, | ||
149 | .ndo_stop = ac_close_card, | ||
150 | |||
151 | .ndo_start_xmit = ei_start_xmit, | ||
152 | .ndo_tx_timeout = ei_tx_timeout, | ||
153 | .ndo_get_stats = ei_get_stats, | ||
154 | .ndo_set_multicast_list = ei_set_multicast_list, | ||
155 | .ndo_validate_addr = eth_validate_addr, | ||
156 | .ndo_set_mac_address = eth_mac_addr, | ||
157 | .ndo_change_mtu = eth_change_mtu, | ||
158 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
159 | .ndo_poll_controller = ei_poll, | ||
160 | #endif | ||
161 | }; | ||
162 | |||
163 | static int __init ac_probe1(int ioaddr, struct net_device *dev) | ||
164 | { | ||
165 | int i, retval; | ||
166 | |||
167 | if (!request_region(ioaddr, AC_IO_EXTENT, DRV_NAME)) | ||
168 | return -EBUSY; | ||
169 | |||
170 | if (inb_p(ioaddr + AC_ID_PORT) == 0xff) { | ||
171 | retval = -ENODEV; | ||
172 | goto out; | ||
173 | } | ||
174 | |||
175 | if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) { | ||
176 | retval = -ENODEV; | ||
177 | goto out; | ||
178 | } | ||
179 | |||
180 | #ifndef final_version | ||
181 | printk(KERN_DEBUG "AC3200 ethercard configuration register is %#02x," | ||
182 | " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG), | ||
183 | inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1), | ||
184 | inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3)); | ||
185 | #endif | ||
186 | |||
187 | for (i = 0; i < 6; i++) | ||
188 | dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i); | ||
189 | |||
190 | printk(KERN_DEBUG "AC3200 in EISA slot %d, node %pM", | ||
191 | ioaddr/0x1000, dev->dev_addr); | ||
192 | #if 0 | ||
193 | /* Check the vendor ID/prefix. Redundant after checking the EISA ID */ | ||
194 | if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0 | ||
195 | || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1 | ||
196 | || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) { | ||
197 | printk(", not found (invalid prefix).\n"); | ||
198 | retval = -ENODEV; | ||
199 | goto out; | ||
200 | } | ||
201 | #endif | ||
202 | |||
203 | /* Assign and allocate the interrupt now. */ | ||
204 | if (dev->irq == 0) { | ||
205 | dev->irq = config2irq(inb(ioaddr + AC_CONFIG)); | ||
206 | printk(", using"); | ||
207 | } else { | ||
208 | dev->irq = irq_canonicalize(dev->irq); | ||
209 | printk(", assigning"); | ||
210 | } | ||
211 | |||
212 | retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev); | ||
213 | if (retval) { | ||
214 | printk (" nothing! Unable to get IRQ %d.\n", dev->irq); | ||
215 | goto out; | ||
216 | } | ||
217 | |||
218 | printk(" IRQ %d, %s port\n", dev->irq, port_name[dev->if_port]); | ||
219 | |||
220 | dev->base_addr = ioaddr; | ||
221 | |||
222 | #ifdef notyet | ||
223 | if (dev->mem_start) { /* Override the value from the board. */ | ||
224 | for (i = 0; i < 7; i++) | ||
225 | if (addrmap[i] == dev->mem_start) | ||
226 | break; | ||
227 | if (i >= 7) | ||
228 | i = 0; | ||
229 | outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG); | ||
230 | } | ||
231 | #endif | ||
232 | |||
233 | dev->if_port = inb(ioaddr + AC_CONFIG) >> 6; | ||
234 | dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG)); | ||
235 | |||
236 | printk("%s: AC3200 at %#3x with %dkB memory at physical address %#lx.\n", | ||
237 | dev->name, ioaddr, AC_STOP_PG/4, dev->mem_start); | ||
238 | |||
239 | /* | ||
240 | * BEWARE!! Some dain-bramaged EISA SCUs will allow you to put | ||
241 | * the card mem within the region covered by `normal' RAM !!! | ||
242 | * | ||
243 | * ioremap() will fail in that case. | ||
244 | */ | ||
245 | ei_status.mem = ioremap(dev->mem_start, AC_STOP_PG*0x100); | ||
246 | if (!ei_status.mem) { | ||
247 | printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n"); | ||
248 | printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n"); | ||
249 | printk(KERN_ERR "ac3200.c: Driver NOT installed.\n"); | ||
250 | retval = -EINVAL; | ||
251 | goto out1; | ||
252 | } | ||
253 | printk("ac3200.c: remapped %dkB card memory to virtual address %p\n", | ||
254 | AC_STOP_PG/4, ei_status.mem); | ||
255 | |||
256 | dev->mem_start = (unsigned long)ei_status.mem; | ||
257 | dev->mem_end = dev->mem_start + (AC_STOP_PG - AC_START_PG)*256; | ||
258 | |||
259 | ei_status.name = "AC3200"; | ||
260 | ei_status.tx_start_page = AC_START_PG; | ||
261 | ei_status.rx_start_page = AC_START_PG + TX_PAGES; | ||
262 | ei_status.stop_page = AC_STOP_PG; | ||
263 | ei_status.word16 = 1; | ||
264 | |||
265 | if (ei_debug > 0) | ||
266 | printk(version); | ||
267 | |||
268 | ei_status.reset_8390 = &ac_reset_8390; | ||
269 | ei_status.block_input = &ac_block_input; | ||
270 | ei_status.block_output = &ac_block_output; | ||
271 | ei_status.get_8390_hdr = &ac_get_8390_hdr; | ||
272 | |||
273 | dev->netdev_ops = &ac_netdev_ops; | ||
274 | NS8390_init(dev, 0); | ||
275 | |||
276 | retval = register_netdev(dev); | ||
277 | if (retval) | ||
278 | goto out2; | ||
279 | return 0; | ||
280 | out2: | ||
281 | if (ei_status.reg0) | ||
282 | iounmap(ei_status.mem); | ||
283 | out1: | ||
284 | free_irq(dev->irq, dev); | ||
285 | out: | ||
286 | release_region(ioaddr, AC_IO_EXTENT); | ||
287 | return retval; | ||
288 | } | ||
289 | |||
290 | static int ac_open(struct net_device *dev) | ||
291 | { | ||
292 | #ifdef notyet | ||
293 | /* Someday we may enable the IRQ and shared memory here. */ | ||
294 | int ioaddr = dev->base_addr; | ||
295 | #endif | ||
296 | |||
297 | ei_open(dev); | ||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static void ac_reset_8390(struct net_device *dev) | ||
302 | { | ||
303 | ushort ioaddr = dev->base_addr; | ||
304 | |||
305 | outb(AC_RESET, ioaddr + AC_RESET_PORT); | ||
306 | if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies); | ||
307 | |||
308 | ei_status.txing = 0; | ||
309 | outb(AC_ENABLE, ioaddr + AC_RESET_PORT); | ||
310 | if (ei_debug > 1) printk("reset done\n"); | ||
311 | } | ||
312 | |||
313 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
314 | we don't need to be concerned with ring wrap as the header will be at | ||
315 | the start of a page, so we optimize accordingly. */ | ||
316 | |||
317 | static void | ||
318 | ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
319 | { | ||
320 | void __iomem *hdr_start = ei_status.mem + ((ring_page - AC_START_PG)<<8); | ||
321 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
322 | } | ||
323 | |||
324 | /* Block input and output are easy on shared memory ethercards, the only | ||
325 | complication is when the ring buffer wraps. */ | ||
326 | |||
327 | static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb, | ||
328 | int ring_offset) | ||
329 | { | ||
330 | void __iomem *start = ei_status.mem + ring_offset - AC_START_PG*256; | ||
331 | |||
332 | if (ring_offset + count > AC_STOP_PG*256) { | ||
333 | /* We must wrap the input move. */ | ||
334 | int semi_count = AC_STOP_PG*256 - ring_offset; | ||
335 | memcpy_fromio(skb->data, start, semi_count); | ||
336 | count -= semi_count; | ||
337 | memcpy_fromio(skb->data + semi_count, | ||
338 | ei_status.mem + TX_PAGES*256, count); | ||
339 | } else { | ||
340 | memcpy_fromio(skb->data, start, count); | ||
341 | } | ||
342 | } | ||
343 | |||
344 | static void ac_block_output(struct net_device *dev, int count, | ||
345 | const unsigned char *buf, int start_page) | ||
346 | { | ||
347 | void __iomem *shmem = ei_status.mem + ((start_page - AC_START_PG)<<8); | ||
348 | |||
349 | memcpy_toio(shmem, buf, count); | ||
350 | } | ||
351 | |||
352 | static int ac_close_card(struct net_device *dev) | ||
353 | { | ||
354 | if (ei_debug > 1) | ||
355 | printk("%s: Shutting down ethercard.\n", dev->name); | ||
356 | |||
357 | #ifdef notyet | ||
358 | /* We should someday disable shared memory and interrupts. */ | ||
359 | outb(0x00, ioaddr + 6); /* Disable interrupts. */ | ||
360 | free_irq(dev->irq, dev); | ||
361 | #endif | ||
362 | |||
363 | ei_close(dev); | ||
364 | return 0; | ||
365 | } | ||
366 | |||
367 | #ifdef MODULE | ||
368 | #define MAX_AC32_CARDS 4 /* Max number of AC32 cards per module */ | ||
369 | static struct net_device *dev_ac32[MAX_AC32_CARDS]; | ||
370 | static int io[MAX_AC32_CARDS]; | ||
371 | static int irq[MAX_AC32_CARDS]; | ||
372 | static int mem[MAX_AC32_CARDS]; | ||
373 | module_param_array(io, int, NULL, 0); | ||
374 | module_param_array(irq, int, NULL, 0); | ||
375 | module_param_array(mem, int, NULL, 0); | ||
376 | MODULE_PARM_DESC(io, "I/O base address(es)"); | ||
377 | MODULE_PARM_DESC(irq, "IRQ number(s)"); | ||
378 | MODULE_PARM_DESC(mem, "Memory base address(es)"); | ||
379 | MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver"); | ||
380 | MODULE_LICENSE("GPL"); | ||
381 | |||
382 | static int __init ac3200_module_init(void) | ||
383 | { | ||
384 | struct net_device *dev; | ||
385 | int this_dev, found = 0; | ||
386 | |||
387 | for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) { | ||
388 | if (io[this_dev] == 0 && this_dev != 0) | ||
389 | break; | ||
390 | dev = alloc_ei_netdev(); | ||
391 | if (!dev) | ||
392 | break; | ||
393 | dev->irq = irq[this_dev]; | ||
394 | dev->base_addr = io[this_dev]; | ||
395 | dev->mem_start = mem[this_dev]; /* Currently ignored by driver */ | ||
396 | if (do_ac3200_probe(dev) == 0) { | ||
397 | dev_ac32[found++] = dev; | ||
398 | continue; | ||
399 | } | ||
400 | free_netdev(dev); | ||
401 | printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]); | ||
402 | break; | ||
403 | } | ||
404 | if (found) | ||
405 | return 0; | ||
406 | return -ENXIO; | ||
407 | } | ||
408 | |||
409 | static void cleanup_card(struct net_device *dev) | ||
410 | { | ||
411 | /* Someday free_irq may be in ac_close_card() */ | ||
412 | free_irq(dev->irq, dev); | ||
413 | release_region(dev->base_addr, AC_IO_EXTENT); | ||
414 | iounmap(ei_status.mem); | ||
415 | } | ||
416 | |||
417 | static void __exit ac3200_module_exit(void) | ||
418 | { | ||
419 | int this_dev; | ||
420 | |||
421 | for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) { | ||
422 | struct net_device *dev = dev_ac32[this_dev]; | ||
423 | if (dev) { | ||
424 | unregister_netdev(dev); | ||
425 | cleanup_card(dev); | ||
426 | free_netdev(dev); | ||
427 | } | ||
428 | } | ||
429 | } | ||
430 | module_init(ac3200_module_init); | ||
431 | module_exit(ac3200_module_exit); | ||
432 | #endif /* MODULE */ | ||
diff --git a/drivers/net/ethernet/8390/apne.c b/drivers/net/ethernet/8390/apne.c new file mode 100644 index 000000000000..547737340cbb --- /dev/null +++ b/drivers/net/ethernet/8390/apne.c | |||
@@ -0,0 +1,620 @@ | |||
1 | /* | ||
2 | * Amiga Linux/68k 8390 based PCMCIA Ethernet Driver for the Amiga 1200 | ||
3 | * | ||
4 | * (C) Copyright 1997 Alain Malek | ||
5 | * (Alain.Malek@cryogen.com) | ||
6 | * | ||
7 | * ---------------------------------------------------------------------------- | ||
8 | * | ||
9 | * This program is based on | ||
10 | * | ||
11 | * ne.c: A general non-shared-memory NS8390 ethernet driver for linux | ||
12 | * Written 1992-94 by Donald Becker. | ||
13 | * | ||
14 | * 8390.c: A general NS8390 ethernet driver core for linux. | ||
15 | * Written 1992-94 by Donald Becker. | ||
16 | * | ||
17 | * cnetdevice: A Sana-II ethernet driver for AmigaOS | ||
18 | * Written by Bruce Abbott (bhabbott@inhb.co.nz) | ||
19 | * | ||
20 | * ---------------------------------------------------------------------------- | ||
21 | * | ||
22 | * This file is subject to the terms and conditions of the GNU General Public | ||
23 | * License. See the file COPYING in the main directory of the Linux | ||
24 | * distribution for more details. | ||
25 | * | ||
26 | * ---------------------------------------------------------------------------- | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | |||
31 | #include <linux/module.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/pci.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/delay.h> | ||
37 | #include <linux/netdevice.h> | ||
38 | #include <linux/etherdevice.h> | ||
39 | #include <linux/interrupt.h> | ||
40 | #include <linux/jiffies.h> | ||
41 | |||
42 | #include <asm/system.h> | ||
43 | #include <asm/io.h> | ||
44 | #include <asm/setup.h> | ||
45 | #include <asm/amigaints.h> | ||
46 | #include <asm/amigahw.h> | ||
47 | #include <asm/amigayle.h> | ||
48 | #include <asm/amipcmcia.h> | ||
49 | |||
50 | #include "8390.h" | ||
51 | |||
52 | /* ---- No user-serviceable parts below ---- */ | ||
53 | |||
54 | #define DRV_NAME "apne" | ||
55 | |||
56 | #define NE_BASE (dev->base_addr) | ||
57 | #define NE_CMD 0x00 | ||
58 | #define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ | ||
59 | #define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */ | ||
60 | #define NE_IO_EXTENT 0x20 | ||
61 | |||
62 | #define NE_EN0_ISR 0x07 | ||
63 | #define NE_EN0_DCFG 0x0e | ||
64 | |||
65 | #define NE_EN0_RSARLO 0x08 | ||
66 | #define NE_EN0_RSARHI 0x09 | ||
67 | #define NE_EN0_RCNTLO 0x0a | ||
68 | #define NE_EN0_RXCR 0x0c | ||
69 | #define NE_EN0_TXCR 0x0d | ||
70 | #define NE_EN0_RCNTHI 0x0b | ||
71 | #define NE_EN0_IMR 0x0f | ||
72 | |||
73 | #define NE1SM_START_PG 0x20 /* First page of TX buffer */ | ||
74 | #define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ | ||
75 | #define NESM_START_PG 0x40 /* First page of TX buffer */ | ||
76 | #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
77 | |||
78 | |||
79 | struct net_device * __init apne_probe(int unit); | ||
80 | static int apne_probe1(struct net_device *dev, int ioaddr); | ||
81 | |||
82 | static void apne_reset_8390(struct net_device *dev); | ||
83 | static void apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
84 | int ring_page); | ||
85 | static void apne_block_input(struct net_device *dev, int count, | ||
86 | struct sk_buff *skb, int ring_offset); | ||
87 | static void apne_block_output(struct net_device *dev, const int count, | ||
88 | const unsigned char *buf, const int start_page); | ||
89 | static irqreturn_t apne_interrupt(int irq, void *dev_id); | ||
90 | |||
91 | static int init_pcmcia(void); | ||
92 | |||
93 | /* IO base address used for nic */ | ||
94 | |||
95 | #define IOBASE 0x300 | ||
96 | |||
97 | /* | ||
98 | use MANUAL_CONFIG and MANUAL_OFFSET for enabling IO by hand | ||
99 | you can find the values to use by looking at the cnet.device | ||
100 | config file example (the default values are for the CNET40BC card) | ||
101 | */ | ||
102 | |||
103 | /* | ||
104 | #define MANUAL_CONFIG 0x20 | ||
105 | #define MANUAL_OFFSET 0x3f8 | ||
106 | |||
107 | #define MANUAL_HWADDR0 0x00 | ||
108 | #define MANUAL_HWADDR1 0x12 | ||
109 | #define MANUAL_HWADDR2 0x34 | ||
110 | #define MANUAL_HWADDR3 0x56 | ||
111 | #define MANUAL_HWADDR4 0x78 | ||
112 | #define MANUAL_HWADDR5 0x9a | ||
113 | */ | ||
114 | |||
115 | static const char version[] = | ||
116 | "apne.c:v1.1 7/10/98 Alain Malek (Alain.Malek@cryogen.ch)\n"; | ||
117 | |||
118 | static int apne_owned; /* signal if card already owned */ | ||
119 | |||
120 | struct net_device * __init apne_probe(int unit) | ||
121 | { | ||
122 | struct net_device *dev; | ||
123 | #ifndef MANUAL_CONFIG | ||
124 | char tuple[8]; | ||
125 | #endif | ||
126 | int err; | ||
127 | |||
128 | if (!MACH_IS_AMIGA) | ||
129 | return ERR_PTR(-ENODEV); | ||
130 | |||
131 | if (apne_owned) | ||
132 | return ERR_PTR(-ENODEV); | ||
133 | |||
134 | if ( !(AMIGAHW_PRESENT(PCMCIA)) ) | ||
135 | return ERR_PTR(-ENODEV); | ||
136 | |||
137 | printk("Looking for PCMCIA ethernet card : "); | ||
138 | |||
139 | /* check if a card is inserted */ | ||
140 | if (!(PCMCIA_INSERTED)) { | ||
141 | printk("NO PCMCIA card inserted\n"); | ||
142 | return ERR_PTR(-ENODEV); | ||
143 | } | ||
144 | |||
145 | dev = alloc_ei_netdev(); | ||
146 | if (!dev) | ||
147 | return ERR_PTR(-ENOMEM); | ||
148 | if (unit >= 0) { | ||
149 | sprintf(dev->name, "eth%d", unit); | ||
150 | netdev_boot_setup_check(dev); | ||
151 | } | ||
152 | |||
153 | /* disable pcmcia irq for readtuple */ | ||
154 | pcmcia_disable_irq(); | ||
155 | |||
156 | #ifndef MANUAL_CONFIG | ||
157 | if ((pcmcia_copy_tuple(CISTPL_FUNCID, tuple, 8) < 3) || | ||
158 | (tuple[2] != CISTPL_FUNCID_NETWORK)) { | ||
159 | printk("not an ethernet card\n"); | ||
160 | /* XXX: shouldn't we re-enable irq here? */ | ||
161 | free_netdev(dev); | ||
162 | return ERR_PTR(-ENODEV); | ||
163 | } | ||
164 | #endif | ||
165 | |||
166 | printk("ethernet PCMCIA card inserted\n"); | ||
167 | |||
168 | if (!init_pcmcia()) { | ||
169 | /* XXX: shouldn't we re-enable irq here? */ | ||
170 | free_netdev(dev); | ||
171 | return ERR_PTR(-ENODEV); | ||
172 | } | ||
173 | |||
174 | if (!request_region(IOBASE, 0x20, DRV_NAME)) { | ||
175 | free_netdev(dev); | ||
176 | return ERR_PTR(-EBUSY); | ||
177 | } | ||
178 | |||
179 | err = apne_probe1(dev, IOBASE); | ||
180 | if (err) { | ||
181 | release_region(IOBASE, 0x20); | ||
182 | free_netdev(dev); | ||
183 | return ERR_PTR(err); | ||
184 | } | ||
185 | err = register_netdev(dev); | ||
186 | if (!err) | ||
187 | return dev; | ||
188 | |||
189 | pcmcia_disable_irq(); | ||
190 | free_irq(IRQ_AMIGA_PORTS, dev); | ||
191 | pcmcia_reset(); | ||
192 | release_region(IOBASE, 0x20); | ||
193 | free_netdev(dev); | ||
194 | return ERR_PTR(err); | ||
195 | } | ||
196 | |||
197 | static int __init apne_probe1(struct net_device *dev, int ioaddr) | ||
198 | { | ||
199 | int i; | ||
200 | unsigned char SA_prom[32]; | ||
201 | int wordlength = 2; | ||
202 | const char *name = NULL; | ||
203 | int start_page, stop_page; | ||
204 | #ifndef MANUAL_HWADDR0 | ||
205 | int neX000, ctron; | ||
206 | #endif | ||
207 | static unsigned version_printed; | ||
208 | |||
209 | if (ei_debug && version_printed++ == 0) | ||
210 | printk(version); | ||
211 | |||
212 | printk("PCMCIA NE*000 ethercard probe"); | ||
213 | |||
214 | /* Reset card. Who knows what dain-bramaged state it was left in. */ | ||
215 | { unsigned long reset_start_time = jiffies; | ||
216 | |||
217 | outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); | ||
218 | |||
219 | while ((inb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) | ||
220 | if (time_after(jiffies, reset_start_time + 2*HZ/100)) { | ||
221 | printk(" not found (no reset ack).\n"); | ||
222 | return -ENODEV; | ||
223 | } | ||
224 | |||
225 | outb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */ | ||
226 | } | ||
227 | |||
228 | #ifndef MANUAL_HWADDR0 | ||
229 | |||
230 | /* Read the 16 bytes of station address PROM. | ||
231 | We must first initialize registers, similar to NS8390_init(eifdev, 0). | ||
232 | We can't reliably read the SAPROM address without this. | ||
233 | (I learned the hard way!). */ | ||
234 | { | ||
235 | struct {unsigned long value, offset; } program_seq[] = { | ||
236 | {E8390_NODMA+E8390_PAGE0+E8390_STOP, NE_CMD}, /* Select page 0*/ | ||
237 | {0x48, NE_EN0_DCFG}, /* Set byte-wide (0x48) access. */ | ||
238 | {0x00, NE_EN0_RCNTLO}, /* Clear the count regs. */ | ||
239 | {0x00, NE_EN0_RCNTHI}, | ||
240 | {0x00, NE_EN0_IMR}, /* Mask completion irq. */ | ||
241 | {0xFF, NE_EN0_ISR}, | ||
242 | {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */ | ||
243 | {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode. */ | ||
244 | {32, NE_EN0_RCNTLO}, | ||
245 | {0x00, NE_EN0_RCNTHI}, | ||
246 | {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000. */ | ||
247 | {0x00, NE_EN0_RSARHI}, | ||
248 | {E8390_RREAD+E8390_START, NE_CMD}, | ||
249 | }; | ||
250 | for (i = 0; i < ARRAY_SIZE(program_seq); i++) { | ||
251 | outb(program_seq[i].value, ioaddr + program_seq[i].offset); | ||
252 | } | ||
253 | |||
254 | } | ||
255 | for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) { | ||
256 | SA_prom[i] = inb(ioaddr + NE_DATAPORT); | ||
257 | SA_prom[i+1] = inb(ioaddr + NE_DATAPORT); | ||
258 | if (SA_prom[i] != SA_prom[i+1]) | ||
259 | wordlength = 1; | ||
260 | } | ||
261 | |||
262 | /* At this point, wordlength *only* tells us if the SA_prom is doubled | ||
263 | up or not because some broken PCI cards don't respect the byte-wide | ||
264 | request in program_seq above, and hence don't have doubled up values. | ||
265 | These broken cards would otherwise be detected as an ne1000. */ | ||
266 | |||
267 | if (wordlength == 2) | ||
268 | for (i = 0; i < 16; i++) | ||
269 | SA_prom[i] = SA_prom[i+i]; | ||
270 | |||
271 | if (wordlength == 2) { | ||
272 | /* We must set the 8390 for word mode. */ | ||
273 | outb(0x49, ioaddr + NE_EN0_DCFG); | ||
274 | start_page = NESM_START_PG; | ||
275 | stop_page = NESM_STOP_PG; | ||
276 | } else { | ||
277 | start_page = NE1SM_START_PG; | ||
278 | stop_page = NE1SM_STOP_PG; | ||
279 | } | ||
280 | |||
281 | neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57); | ||
282 | ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d); | ||
283 | |||
284 | /* Set up the rest of the parameters. */ | ||
285 | if (neX000) { | ||
286 | name = (wordlength == 2) ? "NE2000" : "NE1000"; | ||
287 | } else if (ctron) { | ||
288 | name = (wordlength == 2) ? "Ctron-8" : "Ctron-16"; | ||
289 | start_page = 0x01; | ||
290 | stop_page = (wordlength == 2) ? 0x40 : 0x20; | ||
291 | } else { | ||
292 | printk(" not found.\n"); | ||
293 | return -ENXIO; | ||
294 | |||
295 | } | ||
296 | |||
297 | #else | ||
298 | wordlength = 2; | ||
299 | /* We must set the 8390 for word mode. */ | ||
300 | outb(0x49, ioaddr + NE_EN0_DCFG); | ||
301 | start_page = NESM_START_PG; | ||
302 | stop_page = NESM_STOP_PG; | ||
303 | |||
304 | SA_prom[0] = MANUAL_HWADDR0; | ||
305 | SA_prom[1] = MANUAL_HWADDR1; | ||
306 | SA_prom[2] = MANUAL_HWADDR2; | ||
307 | SA_prom[3] = MANUAL_HWADDR3; | ||
308 | SA_prom[4] = MANUAL_HWADDR4; | ||
309 | SA_prom[5] = MANUAL_HWADDR5; | ||
310 | name = "NE2000"; | ||
311 | #endif | ||
312 | |||
313 | dev->base_addr = ioaddr; | ||
314 | dev->irq = IRQ_AMIGA_PORTS; | ||
315 | dev->netdev_ops = &ei_netdev_ops; | ||
316 | |||
317 | /* Install the Interrupt handler */ | ||
318 | i = request_irq(dev->irq, apne_interrupt, IRQF_SHARED, DRV_NAME, dev); | ||
319 | if (i) return i; | ||
320 | |||
321 | for(i = 0; i < ETHER_ADDR_LEN; i++) | ||
322 | dev->dev_addr[i] = SA_prom[i]; | ||
323 | |||
324 | printk(" %pM\n", dev->dev_addr); | ||
325 | |||
326 | printk("%s: %s found.\n", dev->name, name); | ||
327 | |||
328 | ei_status.name = name; | ||
329 | ei_status.tx_start_page = start_page; | ||
330 | ei_status.stop_page = stop_page; | ||
331 | ei_status.word16 = (wordlength == 2); | ||
332 | |||
333 | ei_status.rx_start_page = start_page + TX_PAGES; | ||
334 | |||
335 | ei_status.reset_8390 = &apne_reset_8390; | ||
336 | ei_status.block_input = &apne_block_input; | ||
337 | ei_status.block_output = &apne_block_output; | ||
338 | ei_status.get_8390_hdr = &apne_get_8390_hdr; | ||
339 | |||
340 | NS8390_init(dev, 0); | ||
341 | |||
342 | pcmcia_ack_int(pcmcia_get_intreq()); /* ack PCMCIA int req */ | ||
343 | pcmcia_enable_irq(); | ||
344 | |||
345 | apne_owned = 1; | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | /* Hard reset the card. This used to pause for the same period that a | ||
351 | 8390 reset command required, but that shouldn't be necessary. */ | ||
352 | static void | ||
353 | apne_reset_8390(struct net_device *dev) | ||
354 | { | ||
355 | unsigned long reset_start_time = jiffies; | ||
356 | |||
357 | init_pcmcia(); | ||
358 | |||
359 | if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies); | ||
360 | |||
361 | outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); | ||
362 | |||
363 | ei_status.txing = 0; | ||
364 | ei_status.dmaing = 0; | ||
365 | |||
366 | /* This check _should_not_ be necessary, omit eventually. */ | ||
367 | while ((inb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0) | ||
368 | if (time_after(jiffies, reset_start_time + 2*HZ/100)) { | ||
369 | printk("%s: ne_reset_8390() did not complete.\n", dev->name); | ||
370 | break; | ||
371 | } | ||
372 | outb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr. */ | ||
373 | } | ||
374 | |||
375 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
376 | we don't need to be concerned with ring wrap as the header will be at | ||
377 | the start of a page, so we optimize accordingly. */ | ||
378 | |||
379 | static void | ||
380 | apne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
381 | { | ||
382 | |||
383 | int nic_base = dev->base_addr; | ||
384 | int cnt; | ||
385 | char *ptrc; | ||
386 | short *ptrs; | ||
387 | |||
388 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
389 | if (ei_status.dmaing) { | ||
390 | printk("%s: DMAing conflict in ne_get_8390_hdr " | ||
391 | "[DMAstat:%d][irqlock:%d][intr:%d].\n", | ||
392 | dev->name, ei_status.dmaing, ei_status.irqlock, dev->irq); | ||
393 | return; | ||
394 | } | ||
395 | |||
396 | ei_status.dmaing |= 0x01; | ||
397 | outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); | ||
398 | outb(ENISR_RDC, nic_base + NE_EN0_ISR); | ||
399 | outb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO); | ||
400 | outb(0, nic_base + NE_EN0_RCNTHI); | ||
401 | outb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */ | ||
402 | outb(ring_page, nic_base + NE_EN0_RSARHI); | ||
403 | outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
404 | |||
405 | if (ei_status.word16) { | ||
406 | ptrs = (short*)hdr; | ||
407 | for(cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++) | ||
408 | *ptrs++ = inw(NE_BASE + NE_DATAPORT); | ||
409 | } else { | ||
410 | ptrc = (char*)hdr; | ||
411 | for(cnt = 0; cnt < sizeof(struct e8390_pkt_hdr); cnt++) | ||
412 | *ptrc++ = inb(NE_BASE + NE_DATAPORT); | ||
413 | } | ||
414 | |||
415 | outb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ | ||
416 | ei_status.dmaing &= ~0x01; | ||
417 | |||
418 | le16_to_cpus(&hdr->count); | ||
419 | } | ||
420 | |||
421 | /* Block input and output, similar to the Crynwr packet driver. If you | ||
422 | are porting to a new ethercard, look at the packet driver source for hints. | ||
423 | The NEx000 doesn't share the on-board packet memory -- you have to put | ||
424 | the packet out through the "remote DMA" dataport using outb. */ | ||
425 | |||
426 | static void | ||
427 | apne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
428 | { | ||
429 | int nic_base = dev->base_addr; | ||
430 | char *buf = skb->data; | ||
431 | char *ptrc; | ||
432 | short *ptrs; | ||
433 | int cnt; | ||
434 | |||
435 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
436 | if (ei_status.dmaing) { | ||
437 | printk("%s: DMAing conflict in ne_block_input " | ||
438 | "[DMAstat:%d][irqlock:%d][intr:%d].\n", | ||
439 | dev->name, ei_status.dmaing, ei_status.irqlock, dev->irq); | ||
440 | return; | ||
441 | } | ||
442 | ei_status.dmaing |= 0x01; | ||
443 | outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); | ||
444 | outb(ENISR_RDC, nic_base + NE_EN0_ISR); | ||
445 | outb(count & 0xff, nic_base + NE_EN0_RCNTLO); | ||
446 | outb(count >> 8, nic_base + NE_EN0_RCNTHI); | ||
447 | outb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO); | ||
448 | outb(ring_offset >> 8, nic_base + NE_EN0_RSARHI); | ||
449 | outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
450 | if (ei_status.word16) { | ||
451 | ptrs = (short*)buf; | ||
452 | for (cnt = 0; cnt < (count>>1); cnt++) | ||
453 | *ptrs++ = inw(NE_BASE + NE_DATAPORT); | ||
454 | if (count & 0x01) { | ||
455 | buf[count-1] = inb(NE_BASE + NE_DATAPORT); | ||
456 | } | ||
457 | } else { | ||
458 | ptrc = (char*)buf; | ||
459 | for (cnt = 0; cnt < count; cnt++) | ||
460 | *ptrc++ = inb(NE_BASE + NE_DATAPORT); | ||
461 | } | ||
462 | |||
463 | outb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ | ||
464 | ei_status.dmaing &= ~0x01; | ||
465 | } | ||
466 | |||
467 | static void | ||
468 | apne_block_output(struct net_device *dev, int count, | ||
469 | const unsigned char *buf, const int start_page) | ||
470 | { | ||
471 | int nic_base = NE_BASE; | ||
472 | unsigned long dma_start; | ||
473 | char *ptrc; | ||
474 | short *ptrs; | ||
475 | int cnt; | ||
476 | |||
477 | /* Round the count up for word writes. Do we need to do this? | ||
478 | What effect will an odd byte count have on the 8390? | ||
479 | I should check someday. */ | ||
480 | if (ei_status.word16 && (count & 0x01)) | ||
481 | count++; | ||
482 | |||
483 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
484 | if (ei_status.dmaing) { | ||
485 | printk("%s: DMAing conflict in ne_block_output." | ||
486 | "[DMAstat:%d][irqlock:%d][intr:%d]\n", | ||
487 | dev->name, ei_status.dmaing, ei_status.irqlock, dev->irq); | ||
488 | return; | ||
489 | } | ||
490 | ei_status.dmaing |= 0x01; | ||
491 | /* We should already be in page 0, but to be safe... */ | ||
492 | outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); | ||
493 | |||
494 | outb(ENISR_RDC, nic_base + NE_EN0_ISR); | ||
495 | |||
496 | /* Now the normal output. */ | ||
497 | outb(count & 0xff, nic_base + NE_EN0_RCNTLO); | ||
498 | outb(count >> 8, nic_base + NE_EN0_RCNTHI); | ||
499 | outb(0x00, nic_base + NE_EN0_RSARLO); | ||
500 | outb(start_page, nic_base + NE_EN0_RSARHI); | ||
501 | |||
502 | outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); | ||
503 | if (ei_status.word16) { | ||
504 | ptrs = (short*)buf; | ||
505 | for (cnt = 0; cnt < count>>1; cnt++) | ||
506 | outw(*ptrs++, NE_BASE+NE_DATAPORT); | ||
507 | } else { | ||
508 | ptrc = (char*)buf; | ||
509 | for (cnt = 0; cnt < count; cnt++) | ||
510 | outb(*ptrc++, NE_BASE + NE_DATAPORT); | ||
511 | } | ||
512 | |||
513 | dma_start = jiffies; | ||
514 | |||
515 | while ((inb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) | ||
516 | if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ | ||
517 | printk("%s: timeout waiting for Tx RDC.\n", dev->name); | ||
518 | apne_reset_8390(dev); | ||
519 | NS8390_init(dev,1); | ||
520 | break; | ||
521 | } | ||
522 | |||
523 | outb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */ | ||
524 | ei_status.dmaing &= ~0x01; | ||
525 | } | ||
526 | |||
527 | static irqreturn_t apne_interrupt(int irq, void *dev_id) | ||
528 | { | ||
529 | unsigned char pcmcia_intreq; | ||
530 | |||
531 | if (!(gayle.inten & GAYLE_IRQ_IRQ)) | ||
532 | return IRQ_NONE; | ||
533 | |||
534 | pcmcia_intreq = pcmcia_get_intreq(); | ||
535 | |||
536 | if (!(pcmcia_intreq & GAYLE_IRQ_IRQ)) { | ||
537 | pcmcia_ack_int(pcmcia_intreq); | ||
538 | return IRQ_NONE; | ||
539 | } | ||
540 | if (ei_debug > 3) | ||
541 | printk("pcmcia intreq = %x\n", pcmcia_intreq); | ||
542 | pcmcia_disable_irq(); /* to get rid of the sti() within ei_interrupt */ | ||
543 | ei_interrupt(irq, dev_id); | ||
544 | pcmcia_ack_int(pcmcia_get_intreq()); | ||
545 | pcmcia_enable_irq(); | ||
546 | return IRQ_HANDLED; | ||
547 | } | ||
548 | |||
549 | #ifdef MODULE | ||
550 | static struct net_device *apne_dev; | ||
551 | |||
552 | static int __init apne_module_init(void) | ||
553 | { | ||
554 | apne_dev = apne_probe(-1); | ||
555 | if (IS_ERR(apne_dev)) | ||
556 | return PTR_ERR(apne_dev); | ||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | static void __exit apne_module_exit(void) | ||
561 | { | ||
562 | unregister_netdev(apne_dev); | ||
563 | |||
564 | pcmcia_disable_irq(); | ||
565 | |||
566 | free_irq(IRQ_AMIGA_PORTS, apne_dev); | ||
567 | |||
568 | pcmcia_reset(); | ||
569 | |||
570 | release_region(IOBASE, 0x20); | ||
571 | |||
572 | free_netdev(apne_dev); | ||
573 | } | ||
574 | module_init(apne_module_init); | ||
575 | module_exit(apne_module_exit); | ||
576 | #endif | ||
577 | |||
578 | static int init_pcmcia(void) | ||
579 | { | ||
580 | u_char config; | ||
581 | #ifndef MANUAL_CONFIG | ||
582 | u_char tuple[32]; | ||
583 | int offset_len; | ||
584 | #endif | ||
585 | u_long offset; | ||
586 | |||
587 | pcmcia_reset(); | ||
588 | pcmcia_program_voltage(PCMCIA_0V); | ||
589 | pcmcia_access_speed(PCMCIA_SPEED_250NS); | ||
590 | pcmcia_write_enable(); | ||
591 | |||
592 | #ifdef MANUAL_CONFIG | ||
593 | config = MANUAL_CONFIG; | ||
594 | #else | ||
595 | /* get and write config byte to enable IO port */ | ||
596 | |||
597 | if (pcmcia_copy_tuple(CISTPL_CFTABLE_ENTRY, tuple, 32) < 3) | ||
598 | return 0; | ||
599 | |||
600 | config = tuple[2] & 0x3f; | ||
601 | #endif | ||
602 | #ifdef MANUAL_OFFSET | ||
603 | offset = MANUAL_OFFSET; | ||
604 | #else | ||
605 | if (pcmcia_copy_tuple(CISTPL_CONFIG, tuple, 32) < 6) | ||
606 | return 0; | ||
607 | |||
608 | offset_len = (tuple[2] & 0x3) + 1; | ||
609 | offset = 0; | ||
610 | while(offset_len--) { | ||
611 | offset = (offset << 8) | tuple[4+offset_len]; | ||
612 | } | ||
613 | #endif | ||
614 | |||
615 | out_8(GAYLE_ATTRIBUTE+offset, config); | ||
616 | |||
617 | return 1; | ||
618 | } | ||
619 | |||
620 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c new file mode 100644 index 000000000000..e7cb8c8b9776 --- /dev/null +++ b/drivers/net/ethernet/8390/ax88796.c | |||
@@ -0,0 +1,1010 @@ | |||
1 | /* drivers/net/ax88796.c | ||
2 | * | ||
3 | * Copyright 2005,2007 Simtec Electronics | ||
4 | * Ben Dooks <ben@simtec.co.uk> | ||
5 | * | ||
6 | * Asix AX88796 10/100 Ethernet controller support | ||
7 | * Based on ne.c, by Donald Becker, et-al. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/isapnp.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/timer.h> | ||
24 | #include <linux/netdevice.h> | ||
25 | #include <linux/etherdevice.h> | ||
26 | #include <linux/ethtool.h> | ||
27 | #include <linux/mdio-bitbang.h> | ||
28 | #include <linux/phy.h> | ||
29 | #include <linux/eeprom_93cx6.h> | ||
30 | #include <linux/slab.h> | ||
31 | |||
32 | #include <net/ax88796.h> | ||
33 | |||
34 | #include <asm/system.h> | ||
35 | |||
36 | /* Rename the lib8390.c functions to show that they are in this driver */ | ||
37 | #define __ei_open ax_ei_open | ||
38 | #define __ei_close ax_ei_close | ||
39 | #define __ei_poll ax_ei_poll | ||
40 | #define __ei_start_xmit ax_ei_start_xmit | ||
41 | #define __ei_tx_timeout ax_ei_tx_timeout | ||
42 | #define __ei_get_stats ax_ei_get_stats | ||
43 | #define __ei_set_multicast_list ax_ei_set_multicast_list | ||
44 | #define __ei_interrupt ax_ei_interrupt | ||
45 | #define ____alloc_ei_netdev ax__alloc_ei_netdev | ||
46 | #define __NS8390_init ax_NS8390_init | ||
47 | |||
48 | /* force unsigned long back to 'void __iomem *' */ | ||
49 | #define ax_convert_addr(_a) ((void __force __iomem *)(_a)) | ||
50 | |||
51 | #define ei_inb(_a) readb(ax_convert_addr(_a)) | ||
52 | #define ei_outb(_v, _a) writeb(_v, ax_convert_addr(_a)) | ||
53 | |||
54 | #define ei_inb_p(_a) ei_inb(_a) | ||
55 | #define ei_outb_p(_v, _a) ei_outb(_v, _a) | ||
56 | |||
57 | /* define EI_SHIFT() to take into account our register offsets */ | ||
58 | #define EI_SHIFT(x) (ei_local->reg_offset[(x)]) | ||
59 | |||
60 | /* Ensure we have our RCR base value */ | ||
61 | #define AX88796_PLATFORM | ||
62 | |||
63 | static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electronics\n"; | ||
64 | |||
65 | #include "lib8390.c" | ||
66 | |||
67 | #define DRV_NAME "ax88796" | ||
68 | #define DRV_VERSION "1.00" | ||
69 | |||
70 | /* from ne.c */ | ||
71 | #define NE_CMD EI_SHIFT(0x00) | ||
72 | #define NE_RESET EI_SHIFT(0x1f) | ||
73 | #define NE_DATAPORT EI_SHIFT(0x10) | ||
74 | |||
75 | #define NE1SM_START_PG 0x20 /* First page of TX buffer */ | ||
76 | #define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ | ||
77 | #define NESM_START_PG 0x40 /* First page of TX buffer */ | ||
78 | #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
79 | |||
80 | #define AX_GPOC_PPDSET BIT(6) | ||
81 | |||
82 | /* device private data */ | ||
83 | |||
84 | struct ax_device { | ||
85 | struct mii_bus *mii_bus; | ||
86 | struct mdiobb_ctrl bb_ctrl; | ||
87 | struct phy_device *phy_dev; | ||
88 | void __iomem *addr_memr; | ||
89 | u8 reg_memr; | ||
90 | int link; | ||
91 | int speed; | ||
92 | int duplex; | ||
93 | |||
94 | void __iomem *map2; | ||
95 | const struct ax_plat_data *plat; | ||
96 | |||
97 | unsigned char running; | ||
98 | unsigned char resume_open; | ||
99 | unsigned int irqflags; | ||
100 | |||
101 | u32 reg_offsets[0x20]; | ||
102 | }; | ||
103 | |||
104 | static inline struct ax_device *to_ax_dev(struct net_device *dev) | ||
105 | { | ||
106 | struct ei_device *ei_local = netdev_priv(dev); | ||
107 | return (struct ax_device *)(ei_local + 1); | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * ax_initial_check | ||
112 | * | ||
113 | * do an initial probe for the card to check wether it exists | ||
114 | * and is functional | ||
115 | */ | ||
116 | static int ax_initial_check(struct net_device *dev) | ||
117 | { | ||
118 | struct ei_device *ei_local = netdev_priv(dev); | ||
119 | void __iomem *ioaddr = ei_local->mem; | ||
120 | int reg0; | ||
121 | int regd; | ||
122 | |||
123 | reg0 = ei_inb(ioaddr); | ||
124 | if (reg0 == 0xFF) | ||
125 | return -ENODEV; | ||
126 | |||
127 | ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, ioaddr + E8390_CMD); | ||
128 | regd = ei_inb(ioaddr + 0x0d); | ||
129 | ei_outb(0xff, ioaddr + 0x0d); | ||
130 | ei_outb(E8390_NODMA + E8390_PAGE0, ioaddr + E8390_CMD); | ||
131 | ei_inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ | ||
132 | if (ei_inb(ioaddr + EN0_COUNTER0) != 0) { | ||
133 | ei_outb(reg0, ioaddr); | ||
134 | ei_outb(regd, ioaddr + 0x0d); /* Restore the old values. */ | ||
135 | return -ENODEV; | ||
136 | } | ||
137 | |||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * Hard reset the card. This used to pause for the same period that a | ||
143 | * 8390 reset command required, but that shouldn't be necessary. | ||
144 | */ | ||
145 | static void ax_reset_8390(struct net_device *dev) | ||
146 | { | ||
147 | struct ei_device *ei_local = netdev_priv(dev); | ||
148 | unsigned long reset_start_time = jiffies; | ||
149 | void __iomem *addr = (void __iomem *)dev->base_addr; | ||
150 | |||
151 | if (ei_debug > 1) | ||
152 | netdev_dbg(dev, "resetting the 8390 t=%ld\n", jiffies); | ||
153 | |||
154 | ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET); | ||
155 | |||
156 | ei_local->txing = 0; | ||
157 | ei_local->dmaing = 0; | ||
158 | |||
159 | /* This check _should_not_ be necessary, omit eventually. */ | ||
160 | while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) { | ||
161 | if (jiffies - reset_start_time > 2 * HZ / 100) { | ||
162 | netdev_warn(dev, "%s: did not complete.\n", __func__); | ||
163 | break; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | ei_outb(ENISR_RESET, addr + EN0_ISR); /* Ack intr. */ | ||
168 | } | ||
169 | |||
170 | |||
171 | static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
172 | int ring_page) | ||
173 | { | ||
174 | struct ei_device *ei_local = netdev_priv(dev); | ||
175 | void __iomem *nic_base = ei_local->mem; | ||
176 | |||
177 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
178 | if (ei_local->dmaing) { | ||
179 | netdev_err(dev, "DMAing conflict in %s " | ||
180 | "[DMAstat:%d][irqlock:%d].\n", | ||
181 | __func__, | ||
182 | ei_local->dmaing, ei_local->irqlock); | ||
183 | return; | ||
184 | } | ||
185 | |||
186 | ei_local->dmaing |= 0x01; | ||
187 | ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); | ||
188 | ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); | ||
189 | ei_outb(0, nic_base + EN0_RCNTHI); | ||
190 | ei_outb(0, nic_base + EN0_RSARLO); /* On page boundary */ | ||
191 | ei_outb(ring_page, nic_base + EN0_RSARHI); | ||
192 | ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
193 | |||
194 | if (ei_local->word16) | ||
195 | readsw(nic_base + NE_DATAPORT, hdr, | ||
196 | sizeof(struct e8390_pkt_hdr) >> 1); | ||
197 | else | ||
198 | readsb(nic_base + NE_DATAPORT, hdr, | ||
199 | sizeof(struct e8390_pkt_hdr)); | ||
200 | |||
201 | ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
202 | ei_local->dmaing &= ~0x01; | ||
203 | |||
204 | le16_to_cpus(&hdr->count); | ||
205 | } | ||
206 | |||
207 | |||
208 | /* | ||
209 | * Block input and output, similar to the Crynwr packet driver. If | ||
210 | * you are porting to a new ethercard, look at the packet driver | ||
211 | * source for hints. The NEx000 doesn't share the on-board packet | ||
212 | * memory -- you have to put the packet out through the "remote DMA" | ||
213 | * dataport using ei_outb. | ||
214 | */ | ||
215 | static void ax_block_input(struct net_device *dev, int count, | ||
216 | struct sk_buff *skb, int ring_offset) | ||
217 | { | ||
218 | struct ei_device *ei_local = netdev_priv(dev); | ||
219 | void __iomem *nic_base = ei_local->mem; | ||
220 | char *buf = skb->data; | ||
221 | |||
222 | if (ei_local->dmaing) { | ||
223 | netdev_err(dev, | ||
224 | "DMAing conflict in %s " | ||
225 | "[DMAstat:%d][irqlock:%d].\n", | ||
226 | __func__, | ||
227 | ei_local->dmaing, ei_local->irqlock); | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | ei_local->dmaing |= 0x01; | ||
232 | |||
233 | ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + NE_CMD); | ||
234 | ei_outb(count & 0xff, nic_base + EN0_RCNTLO); | ||
235 | ei_outb(count >> 8, nic_base + EN0_RCNTHI); | ||
236 | ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO); | ||
237 | ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI); | ||
238 | ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
239 | |||
240 | if (ei_local->word16) { | ||
241 | readsw(nic_base + NE_DATAPORT, buf, count >> 1); | ||
242 | if (count & 0x01) | ||
243 | buf[count-1] = ei_inb(nic_base + NE_DATAPORT); | ||
244 | |||
245 | } else { | ||
246 | readsb(nic_base + NE_DATAPORT, buf, count); | ||
247 | } | ||
248 | |||
249 | ei_local->dmaing &= ~1; | ||
250 | } | ||
251 | |||
252 | static void ax_block_output(struct net_device *dev, int count, | ||
253 | const unsigned char *buf, const int start_page) | ||
254 | { | ||
255 | struct ei_device *ei_local = netdev_priv(dev); | ||
256 | void __iomem *nic_base = ei_local->mem; | ||
257 | unsigned long dma_start; | ||
258 | |||
259 | /* | ||
260 | * Round the count up for word writes. Do we need to do this? | ||
261 | * What effect will an odd byte count have on the 8390? I | ||
262 | * should check someday. | ||
263 | */ | ||
264 | if (ei_local->word16 && (count & 0x01)) | ||
265 | count++; | ||
266 | |||
267 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
268 | if (ei_local->dmaing) { | ||
269 | netdev_err(dev, "DMAing conflict in %s." | ||
270 | "[DMAstat:%d][irqlock:%d]\n", | ||
271 | __func__, | ||
272 | ei_local->dmaing, ei_local->irqlock); | ||
273 | return; | ||
274 | } | ||
275 | |||
276 | ei_local->dmaing |= 0x01; | ||
277 | /* We should already be in page 0, but to be safe... */ | ||
278 | ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); | ||
279 | |||
280 | ei_outb(ENISR_RDC, nic_base + EN0_ISR); | ||
281 | |||
282 | /* Now the normal output. */ | ||
283 | ei_outb(count & 0xff, nic_base + EN0_RCNTLO); | ||
284 | ei_outb(count >> 8, nic_base + EN0_RCNTHI); | ||
285 | ei_outb(0x00, nic_base + EN0_RSARLO); | ||
286 | ei_outb(start_page, nic_base + EN0_RSARHI); | ||
287 | |||
288 | ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); | ||
289 | if (ei_local->word16) | ||
290 | writesw(nic_base + NE_DATAPORT, buf, count >> 1); | ||
291 | else | ||
292 | writesb(nic_base + NE_DATAPORT, buf, count); | ||
293 | |||
294 | dma_start = jiffies; | ||
295 | |||
296 | while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) { | ||
297 | if (jiffies - dma_start > 2 * HZ / 100) { /* 20ms */ | ||
298 | netdev_warn(dev, "timeout waiting for Tx RDC.\n"); | ||
299 | ax_reset_8390(dev); | ||
300 | ax_NS8390_init(dev, 1); | ||
301 | break; | ||
302 | } | ||
303 | } | ||
304 | |||
305 | ei_outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
306 | ei_local->dmaing &= ~0x01; | ||
307 | } | ||
308 | |||
309 | /* definitions for accessing MII/EEPROM interface */ | ||
310 | |||
311 | #define AX_MEMR EI_SHIFT(0x14) | ||
312 | #define AX_MEMR_MDC BIT(0) | ||
313 | #define AX_MEMR_MDIR BIT(1) | ||
314 | #define AX_MEMR_MDI BIT(2) | ||
315 | #define AX_MEMR_MDO BIT(3) | ||
316 | #define AX_MEMR_EECS BIT(4) | ||
317 | #define AX_MEMR_EEI BIT(5) | ||
318 | #define AX_MEMR_EEO BIT(6) | ||
319 | #define AX_MEMR_EECLK BIT(7) | ||
320 | |||
321 | static void ax_handle_link_change(struct net_device *dev) | ||
322 | { | ||
323 | struct ax_device *ax = to_ax_dev(dev); | ||
324 | struct phy_device *phy_dev = ax->phy_dev; | ||
325 | int status_change = 0; | ||
326 | |||
327 | if (phy_dev->link && ((ax->speed != phy_dev->speed) || | ||
328 | (ax->duplex != phy_dev->duplex))) { | ||
329 | |||
330 | ax->speed = phy_dev->speed; | ||
331 | ax->duplex = phy_dev->duplex; | ||
332 | status_change = 1; | ||
333 | } | ||
334 | |||
335 | if (phy_dev->link != ax->link) { | ||
336 | if (!phy_dev->link) { | ||
337 | ax->speed = 0; | ||
338 | ax->duplex = -1; | ||
339 | } | ||
340 | ax->link = phy_dev->link; | ||
341 | |||
342 | status_change = 1; | ||
343 | } | ||
344 | |||
345 | if (status_change) | ||
346 | phy_print_status(phy_dev); | ||
347 | } | ||
348 | |||
349 | static int ax_mii_probe(struct net_device *dev) | ||
350 | { | ||
351 | struct ax_device *ax = to_ax_dev(dev); | ||
352 | struct phy_device *phy_dev = NULL; | ||
353 | int ret; | ||
354 | |||
355 | /* find the first phy */ | ||
356 | phy_dev = phy_find_first(ax->mii_bus); | ||
357 | if (!phy_dev) { | ||
358 | netdev_err(dev, "no PHY found\n"); | ||
359 | return -ENODEV; | ||
360 | } | ||
361 | |||
362 | ret = phy_connect_direct(dev, phy_dev, ax_handle_link_change, 0, | ||
363 | PHY_INTERFACE_MODE_MII); | ||
364 | if (ret) { | ||
365 | netdev_err(dev, "Could not attach to PHY\n"); | ||
366 | return ret; | ||
367 | } | ||
368 | |||
369 | /* mask with MAC supported features */ | ||
370 | phy_dev->supported &= PHY_BASIC_FEATURES; | ||
371 | phy_dev->advertising = phy_dev->supported; | ||
372 | |||
373 | ax->phy_dev = phy_dev; | ||
374 | |||
375 | netdev_info(dev, "PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", | ||
376 | phy_dev->drv->name, dev_name(&phy_dev->dev), phy_dev->irq); | ||
377 | |||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static void ax_phy_switch(struct net_device *dev, int on) | ||
382 | { | ||
383 | struct ei_device *ei_local = netdev_priv(dev); | ||
384 | struct ax_device *ax = to_ax_dev(dev); | ||
385 | |||
386 | u8 reg_gpoc = ax->plat->gpoc_val; | ||
387 | |||
388 | if (!!on) | ||
389 | reg_gpoc &= ~AX_GPOC_PPDSET; | ||
390 | else | ||
391 | reg_gpoc |= AX_GPOC_PPDSET; | ||
392 | |||
393 | ei_outb(reg_gpoc, ei_local->mem + EI_SHIFT(0x17)); | ||
394 | } | ||
395 | |||
396 | static int ax_open(struct net_device *dev) | ||
397 | { | ||
398 | struct ax_device *ax = to_ax_dev(dev); | ||
399 | int ret; | ||
400 | |||
401 | netdev_dbg(dev, "open\n"); | ||
402 | |||
403 | ret = request_irq(dev->irq, ax_ei_interrupt, ax->irqflags, | ||
404 | dev->name, dev); | ||
405 | if (ret) | ||
406 | goto failed_request_irq; | ||
407 | |||
408 | /* turn the phy on (if turned off) */ | ||
409 | ax_phy_switch(dev, 1); | ||
410 | |||
411 | ret = ax_mii_probe(dev); | ||
412 | if (ret) | ||
413 | goto failed_mii_probe; | ||
414 | phy_start(ax->phy_dev); | ||
415 | |||
416 | ret = ax_ei_open(dev); | ||
417 | if (ret) | ||
418 | goto failed_ax_ei_open; | ||
419 | |||
420 | ax->running = 1; | ||
421 | |||
422 | return 0; | ||
423 | |||
424 | failed_ax_ei_open: | ||
425 | phy_disconnect(ax->phy_dev); | ||
426 | failed_mii_probe: | ||
427 | ax_phy_switch(dev, 0); | ||
428 | free_irq(dev->irq, dev); | ||
429 | failed_request_irq: | ||
430 | return ret; | ||
431 | } | ||
432 | |||
433 | static int ax_close(struct net_device *dev) | ||
434 | { | ||
435 | struct ax_device *ax = to_ax_dev(dev); | ||
436 | |||
437 | netdev_dbg(dev, "close\n"); | ||
438 | |||
439 | ax->running = 0; | ||
440 | wmb(); | ||
441 | |||
442 | ax_ei_close(dev); | ||
443 | |||
444 | /* turn the phy off */ | ||
445 | ax_phy_switch(dev, 0); | ||
446 | phy_disconnect(ax->phy_dev); | ||
447 | |||
448 | free_irq(dev->irq, dev); | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd) | ||
453 | { | ||
454 | struct ax_device *ax = to_ax_dev(dev); | ||
455 | struct phy_device *phy_dev = ax->phy_dev; | ||
456 | |||
457 | if (!netif_running(dev)) | ||
458 | return -EINVAL; | ||
459 | |||
460 | if (!phy_dev) | ||
461 | return -ENODEV; | ||
462 | |||
463 | return phy_mii_ioctl(phy_dev, req, cmd); | ||
464 | } | ||
465 | |||
466 | /* ethtool ops */ | ||
467 | |||
468 | static void ax_get_drvinfo(struct net_device *dev, | ||
469 | struct ethtool_drvinfo *info) | ||
470 | { | ||
471 | struct platform_device *pdev = to_platform_device(dev->dev.parent); | ||
472 | |||
473 | strcpy(info->driver, DRV_NAME); | ||
474 | strcpy(info->version, DRV_VERSION); | ||
475 | strcpy(info->bus_info, pdev->name); | ||
476 | } | ||
477 | |||
478 | static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
479 | { | ||
480 | struct ax_device *ax = to_ax_dev(dev); | ||
481 | struct phy_device *phy_dev = ax->phy_dev; | ||
482 | |||
483 | if (!phy_dev) | ||
484 | return -ENODEV; | ||
485 | |||
486 | return phy_ethtool_gset(phy_dev, cmd); | ||
487 | } | ||
488 | |||
489 | static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
490 | { | ||
491 | struct ax_device *ax = to_ax_dev(dev); | ||
492 | struct phy_device *phy_dev = ax->phy_dev; | ||
493 | |||
494 | if (!phy_dev) | ||
495 | return -ENODEV; | ||
496 | |||
497 | return phy_ethtool_sset(phy_dev, cmd); | ||
498 | } | ||
499 | |||
500 | static const struct ethtool_ops ax_ethtool_ops = { | ||
501 | .get_drvinfo = ax_get_drvinfo, | ||
502 | .get_settings = ax_get_settings, | ||
503 | .set_settings = ax_set_settings, | ||
504 | .get_link = ethtool_op_get_link, | ||
505 | }; | ||
506 | |||
507 | #ifdef CONFIG_AX88796_93CX6 | ||
508 | static void ax_eeprom_register_read(struct eeprom_93cx6 *eeprom) | ||
509 | { | ||
510 | struct ei_device *ei_local = eeprom->data; | ||
511 | u8 reg = ei_inb(ei_local->mem + AX_MEMR); | ||
512 | |||
513 | eeprom->reg_data_in = reg & AX_MEMR_EEI; | ||
514 | eeprom->reg_data_out = reg & AX_MEMR_EEO; /* Input pin */ | ||
515 | eeprom->reg_data_clock = reg & AX_MEMR_EECLK; | ||
516 | eeprom->reg_chip_select = reg & AX_MEMR_EECS; | ||
517 | } | ||
518 | |||
519 | static void ax_eeprom_register_write(struct eeprom_93cx6 *eeprom) | ||
520 | { | ||
521 | struct ei_device *ei_local = eeprom->data; | ||
522 | u8 reg = ei_inb(ei_local->mem + AX_MEMR); | ||
523 | |||
524 | reg &= ~(AX_MEMR_EEI | AX_MEMR_EECLK | AX_MEMR_EECS); | ||
525 | |||
526 | if (eeprom->reg_data_in) | ||
527 | reg |= AX_MEMR_EEI; | ||
528 | if (eeprom->reg_data_clock) | ||
529 | reg |= AX_MEMR_EECLK; | ||
530 | if (eeprom->reg_chip_select) | ||
531 | reg |= AX_MEMR_EECS; | ||
532 | |||
533 | ei_outb(reg, ei_local->mem + AX_MEMR); | ||
534 | udelay(10); | ||
535 | } | ||
536 | #endif | ||
537 | |||
538 | static const struct net_device_ops ax_netdev_ops = { | ||
539 | .ndo_open = ax_open, | ||
540 | .ndo_stop = ax_close, | ||
541 | .ndo_do_ioctl = ax_ioctl, | ||
542 | |||
543 | .ndo_start_xmit = ax_ei_start_xmit, | ||
544 | .ndo_tx_timeout = ax_ei_tx_timeout, | ||
545 | .ndo_get_stats = ax_ei_get_stats, | ||
546 | .ndo_set_multicast_list = ax_ei_set_multicast_list, | ||
547 | .ndo_validate_addr = eth_validate_addr, | ||
548 | .ndo_set_mac_address = eth_mac_addr, | ||
549 | .ndo_change_mtu = eth_change_mtu, | ||
550 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
551 | .ndo_poll_controller = ax_ei_poll, | ||
552 | #endif | ||
553 | }; | ||
554 | |||
555 | static void ax_bb_mdc(struct mdiobb_ctrl *ctrl, int level) | ||
556 | { | ||
557 | struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl); | ||
558 | |||
559 | if (level) | ||
560 | ax->reg_memr |= AX_MEMR_MDC; | ||
561 | else | ||
562 | ax->reg_memr &= ~AX_MEMR_MDC; | ||
563 | |||
564 | ei_outb(ax->reg_memr, ax->addr_memr); | ||
565 | } | ||
566 | |||
567 | static void ax_bb_dir(struct mdiobb_ctrl *ctrl, int output) | ||
568 | { | ||
569 | struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl); | ||
570 | |||
571 | if (output) | ||
572 | ax->reg_memr &= ~AX_MEMR_MDIR; | ||
573 | else | ||
574 | ax->reg_memr |= AX_MEMR_MDIR; | ||
575 | |||
576 | ei_outb(ax->reg_memr, ax->addr_memr); | ||
577 | } | ||
578 | |||
579 | static void ax_bb_set_data(struct mdiobb_ctrl *ctrl, int value) | ||
580 | { | ||
581 | struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl); | ||
582 | |||
583 | if (value) | ||
584 | ax->reg_memr |= AX_MEMR_MDO; | ||
585 | else | ||
586 | ax->reg_memr &= ~AX_MEMR_MDO; | ||
587 | |||
588 | ei_outb(ax->reg_memr, ax->addr_memr); | ||
589 | } | ||
590 | |||
591 | static int ax_bb_get_data(struct mdiobb_ctrl *ctrl) | ||
592 | { | ||
593 | struct ax_device *ax = container_of(ctrl, struct ax_device, bb_ctrl); | ||
594 | int reg_memr = ei_inb(ax->addr_memr); | ||
595 | |||
596 | return reg_memr & AX_MEMR_MDI ? 1 : 0; | ||
597 | } | ||
598 | |||
599 | static struct mdiobb_ops bb_ops = { | ||
600 | .owner = THIS_MODULE, | ||
601 | .set_mdc = ax_bb_mdc, | ||
602 | .set_mdio_dir = ax_bb_dir, | ||
603 | .set_mdio_data = ax_bb_set_data, | ||
604 | .get_mdio_data = ax_bb_get_data, | ||
605 | }; | ||
606 | |||
607 | /* setup code */ | ||
608 | |||
609 | static int ax_mii_init(struct net_device *dev) | ||
610 | { | ||
611 | struct platform_device *pdev = to_platform_device(dev->dev.parent); | ||
612 | struct ei_device *ei_local = netdev_priv(dev); | ||
613 | struct ax_device *ax = to_ax_dev(dev); | ||
614 | int err, i; | ||
615 | |||
616 | ax->bb_ctrl.ops = &bb_ops; | ||
617 | ax->addr_memr = ei_local->mem + AX_MEMR; | ||
618 | ax->mii_bus = alloc_mdio_bitbang(&ax->bb_ctrl); | ||
619 | if (!ax->mii_bus) { | ||
620 | err = -ENOMEM; | ||
621 | goto out; | ||
622 | } | ||
623 | |||
624 | ax->mii_bus->name = "ax88796_mii_bus"; | ||
625 | ax->mii_bus->parent = dev->dev.parent; | ||
626 | snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id); | ||
627 | |||
628 | ax->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); | ||
629 | if (!ax->mii_bus->irq) { | ||
630 | err = -ENOMEM; | ||
631 | goto out_free_mdio_bitbang; | ||
632 | } | ||
633 | |||
634 | for (i = 0; i < PHY_MAX_ADDR; i++) | ||
635 | ax->mii_bus->irq[i] = PHY_POLL; | ||
636 | |||
637 | err = mdiobus_register(ax->mii_bus); | ||
638 | if (err) | ||
639 | goto out_free_irq; | ||
640 | |||
641 | return 0; | ||
642 | |||
643 | out_free_irq: | ||
644 | kfree(ax->mii_bus->irq); | ||
645 | out_free_mdio_bitbang: | ||
646 | free_mdio_bitbang(ax->mii_bus); | ||
647 | out: | ||
648 | return err; | ||
649 | } | ||
650 | |||
651 | static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local) | ||
652 | { | ||
653 | void __iomem *ioaddr = ei_local->mem; | ||
654 | struct ax_device *ax = to_ax_dev(dev); | ||
655 | |||
656 | /* Select page 0 */ | ||
657 | ei_outb(E8390_NODMA + E8390_PAGE0 + E8390_STOP, ioaddr + E8390_CMD); | ||
658 | |||
659 | /* set to byte access */ | ||
660 | ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG); | ||
661 | ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17)); | ||
662 | } | ||
663 | |||
664 | /* | ||
665 | * ax_init_dev | ||
666 | * | ||
667 | * initialise the specified device, taking care to note the MAC | ||
668 | * address it may already have (if configured), ensure | ||
669 | * the device is ready to be used by lib8390.c and registerd with | ||
670 | * the network layer. | ||
671 | */ | ||
672 | static int ax_init_dev(struct net_device *dev) | ||
673 | { | ||
674 | struct ei_device *ei_local = netdev_priv(dev); | ||
675 | struct ax_device *ax = to_ax_dev(dev); | ||
676 | void __iomem *ioaddr = ei_local->mem; | ||
677 | unsigned int start_page; | ||
678 | unsigned int stop_page; | ||
679 | int ret; | ||
680 | int i; | ||
681 | |||
682 | ret = ax_initial_check(dev); | ||
683 | if (ret) | ||
684 | goto err_out; | ||
685 | |||
686 | /* setup goes here */ | ||
687 | |||
688 | ax_initial_setup(dev, ei_local); | ||
689 | |||
690 | /* read the mac from the card prom if we need it */ | ||
691 | |||
692 | if (ax->plat->flags & AXFLG_HAS_EEPROM) { | ||
693 | unsigned char SA_prom[32]; | ||
694 | |||
695 | for (i = 0; i < sizeof(SA_prom); i += 2) { | ||
696 | SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT); | ||
697 | SA_prom[i + 1] = ei_inb(ioaddr + NE_DATAPORT); | ||
698 | } | ||
699 | |||
700 | if (ax->plat->wordlength == 2) | ||
701 | for (i = 0; i < 16; i++) | ||
702 | SA_prom[i] = SA_prom[i+i]; | ||
703 | |||
704 | memcpy(dev->dev_addr, SA_prom, 6); | ||
705 | } | ||
706 | |||
707 | #ifdef CONFIG_AX88796_93CX6 | ||
708 | if (ax->plat->flags & AXFLG_HAS_93CX6) { | ||
709 | unsigned char mac_addr[6]; | ||
710 | struct eeprom_93cx6 eeprom; | ||
711 | |||
712 | eeprom.data = ei_local; | ||
713 | eeprom.register_read = ax_eeprom_register_read; | ||
714 | eeprom.register_write = ax_eeprom_register_write; | ||
715 | eeprom.width = PCI_EEPROM_WIDTH_93C56; | ||
716 | |||
717 | eeprom_93cx6_multiread(&eeprom, 0, | ||
718 | (__le16 __force *)mac_addr, | ||
719 | sizeof(mac_addr) >> 1); | ||
720 | |||
721 | memcpy(dev->dev_addr, mac_addr, 6); | ||
722 | } | ||
723 | #endif | ||
724 | if (ax->plat->wordlength == 2) { | ||
725 | /* We must set the 8390 for word mode. */ | ||
726 | ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG); | ||
727 | start_page = NESM_START_PG; | ||
728 | stop_page = NESM_STOP_PG; | ||
729 | } else { | ||
730 | start_page = NE1SM_START_PG; | ||
731 | stop_page = NE1SM_STOP_PG; | ||
732 | } | ||
733 | |||
734 | /* load the mac-address from the device */ | ||
735 | if (ax->plat->flags & AXFLG_MAC_FROMDEV) { | ||
736 | ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP, | ||
737 | ei_local->mem + E8390_CMD); /* 0x61 */ | ||
738 | for (i = 0; i < ETHER_ADDR_LEN; i++) | ||
739 | dev->dev_addr[i] = | ||
740 | ei_inb(ioaddr + EN1_PHYS_SHIFT(i)); | ||
741 | } | ||
742 | |||
743 | if ((ax->plat->flags & AXFLG_MAC_FROMPLATFORM) && | ||
744 | ax->plat->mac_addr) | ||
745 | memcpy(dev->dev_addr, ax->plat->mac_addr, | ||
746 | ETHER_ADDR_LEN); | ||
747 | |||
748 | ax_reset_8390(dev); | ||
749 | |||
750 | ei_local->name = "AX88796"; | ||
751 | ei_local->tx_start_page = start_page; | ||
752 | ei_local->stop_page = stop_page; | ||
753 | ei_local->word16 = (ax->plat->wordlength == 2); | ||
754 | ei_local->rx_start_page = start_page + TX_PAGES; | ||
755 | |||
756 | #ifdef PACKETBUF_MEMSIZE | ||
757 | /* Allow the packet buffer size to be overridden by know-it-alls. */ | ||
758 | ei_local->stop_page = ei_local->tx_start_page + PACKETBUF_MEMSIZE; | ||
759 | #endif | ||
760 | |||
761 | ei_local->reset_8390 = &ax_reset_8390; | ||
762 | ei_local->block_input = &ax_block_input; | ||
763 | ei_local->block_output = &ax_block_output; | ||
764 | ei_local->get_8390_hdr = &ax_get_8390_hdr; | ||
765 | ei_local->priv = 0; | ||
766 | |||
767 | dev->netdev_ops = &ax_netdev_ops; | ||
768 | dev->ethtool_ops = &ax_ethtool_ops; | ||
769 | |||
770 | ret = ax_mii_init(dev); | ||
771 | if (ret) | ||
772 | goto out_irq; | ||
773 | |||
774 | ax_NS8390_init(dev, 0); | ||
775 | |||
776 | ret = register_netdev(dev); | ||
777 | if (ret) | ||
778 | goto out_irq; | ||
779 | |||
780 | netdev_info(dev, "%dbit, irq %d, %lx, MAC: %pM\n", | ||
781 | ei_local->word16 ? 16 : 8, dev->irq, dev->base_addr, | ||
782 | dev->dev_addr); | ||
783 | |||
784 | return 0; | ||
785 | |||
786 | out_irq: | ||
787 | /* cleanup irq */ | ||
788 | free_irq(dev->irq, dev); | ||
789 | err_out: | ||
790 | return ret; | ||
791 | } | ||
792 | |||
793 | static int ax_remove(struct platform_device *pdev) | ||
794 | { | ||
795 | struct net_device *dev = platform_get_drvdata(pdev); | ||
796 | struct ei_device *ei_local = netdev_priv(dev); | ||
797 | struct ax_device *ax = to_ax_dev(dev); | ||
798 | struct resource *mem; | ||
799 | |||
800 | unregister_netdev(dev); | ||
801 | free_irq(dev->irq, dev); | ||
802 | |||
803 | iounmap(ei_local->mem); | ||
804 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
805 | release_mem_region(mem->start, resource_size(mem)); | ||
806 | |||
807 | if (ax->map2) { | ||
808 | iounmap(ax->map2); | ||
809 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
810 | release_mem_region(mem->start, resource_size(mem)); | ||
811 | } | ||
812 | |||
813 | free_netdev(dev); | ||
814 | |||
815 | return 0; | ||
816 | } | ||
817 | |||
818 | /* | ||
819 | * ax_probe | ||
820 | * | ||
821 | * This is the entry point when the platform device system uses to | ||
822 | * notify us of a new device to attach to. Allocate memory, find the | ||
823 | * resources and information passed, and map the necessary registers. | ||
824 | */ | ||
825 | static int ax_probe(struct platform_device *pdev) | ||
826 | { | ||
827 | struct net_device *dev; | ||
828 | struct ei_device *ei_local; | ||
829 | struct ax_device *ax; | ||
830 | struct resource *irq, *mem, *mem2; | ||
831 | resource_size_t mem_size, mem2_size = 0; | ||
832 | int ret = 0; | ||
833 | |||
834 | dev = ax__alloc_ei_netdev(sizeof(struct ax_device)); | ||
835 | if (dev == NULL) | ||
836 | return -ENOMEM; | ||
837 | |||
838 | /* ok, let's setup our device */ | ||
839 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
840 | ei_local = netdev_priv(dev); | ||
841 | ax = to_ax_dev(dev); | ||
842 | |||
843 | ax->plat = pdev->dev.platform_data; | ||
844 | platform_set_drvdata(pdev, dev); | ||
845 | |||
846 | ei_local->rxcr_base = ax->plat->rcr_val; | ||
847 | |||
848 | /* find the platform resources */ | ||
849 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
850 | if (!irq) { | ||
851 | dev_err(&pdev->dev, "no IRQ specified\n"); | ||
852 | ret = -ENXIO; | ||
853 | goto exit_mem; | ||
854 | } | ||
855 | |||
856 | dev->irq = irq->start; | ||
857 | ax->irqflags = irq->flags & IRQF_TRIGGER_MASK; | ||
858 | |||
859 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
860 | if (!mem) { | ||
861 | dev_err(&pdev->dev, "no MEM specified\n"); | ||
862 | ret = -ENXIO; | ||
863 | goto exit_mem; | ||
864 | } | ||
865 | |||
866 | mem_size = resource_size(mem); | ||
867 | |||
868 | /* | ||
869 | * setup the register offsets from either the platform data or | ||
870 | * by using the size of the resource provided | ||
871 | */ | ||
872 | if (ax->plat->reg_offsets) | ||
873 | ei_local->reg_offset = ax->plat->reg_offsets; | ||
874 | else { | ||
875 | ei_local->reg_offset = ax->reg_offsets; | ||
876 | for (ret = 0; ret < 0x18; ret++) | ||
877 | ax->reg_offsets[ret] = (mem_size / 0x18) * ret; | ||
878 | } | ||
879 | |||
880 | if (!request_mem_region(mem->start, mem_size, pdev->name)) { | ||
881 | dev_err(&pdev->dev, "cannot reserve registers\n"); | ||
882 | ret = -ENXIO; | ||
883 | goto exit_mem; | ||
884 | } | ||
885 | |||
886 | ei_local->mem = ioremap(mem->start, mem_size); | ||
887 | dev->base_addr = (unsigned long)ei_local->mem; | ||
888 | |||
889 | if (ei_local->mem == NULL) { | ||
890 | dev_err(&pdev->dev, "Cannot ioremap area %pR\n", mem); | ||
891 | |||
892 | ret = -ENXIO; | ||
893 | goto exit_req; | ||
894 | } | ||
895 | |||
896 | /* look for reset area */ | ||
897 | mem2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
898 | if (!mem2) { | ||
899 | if (!ax->plat->reg_offsets) { | ||
900 | for (ret = 0; ret < 0x20; ret++) | ||
901 | ax->reg_offsets[ret] = (mem_size / 0x20) * ret; | ||
902 | } | ||
903 | } else { | ||
904 | mem2_size = resource_size(mem2); | ||
905 | |||
906 | if (!request_mem_region(mem2->start, mem2_size, pdev->name)) { | ||
907 | dev_err(&pdev->dev, "cannot reserve registers\n"); | ||
908 | ret = -ENXIO; | ||
909 | goto exit_mem1; | ||
910 | } | ||
911 | |||
912 | ax->map2 = ioremap(mem2->start, mem2_size); | ||
913 | if (!ax->map2) { | ||
914 | dev_err(&pdev->dev, "cannot map reset register\n"); | ||
915 | ret = -ENXIO; | ||
916 | goto exit_mem2; | ||
917 | } | ||
918 | |||
919 | ei_local->reg_offset[0x1f] = ax->map2 - ei_local->mem; | ||
920 | } | ||
921 | |||
922 | /* got resources, now initialise and register device */ | ||
923 | ret = ax_init_dev(dev); | ||
924 | if (!ret) | ||
925 | return 0; | ||
926 | |||
927 | if (!ax->map2) | ||
928 | goto exit_mem1; | ||
929 | |||
930 | iounmap(ax->map2); | ||
931 | |||
932 | exit_mem2: | ||
933 | release_mem_region(mem2->start, mem2_size); | ||
934 | |||
935 | exit_mem1: | ||
936 | iounmap(ei_local->mem); | ||
937 | |||
938 | exit_req: | ||
939 | release_mem_region(mem->start, mem_size); | ||
940 | |||
941 | exit_mem: | ||
942 | free_netdev(dev); | ||
943 | |||
944 | return ret; | ||
945 | } | ||
946 | |||
947 | /* suspend and resume */ | ||
948 | |||
949 | #ifdef CONFIG_PM | ||
950 | static int ax_suspend(struct platform_device *dev, pm_message_t state) | ||
951 | { | ||
952 | struct net_device *ndev = platform_get_drvdata(dev); | ||
953 | struct ax_device *ax = to_ax_dev(ndev); | ||
954 | |||
955 | ax->resume_open = ax->running; | ||
956 | |||
957 | netif_device_detach(ndev); | ||
958 | ax_close(ndev); | ||
959 | |||
960 | return 0; | ||
961 | } | ||
962 | |||
963 | static int ax_resume(struct platform_device *pdev) | ||
964 | { | ||
965 | struct net_device *ndev = platform_get_drvdata(pdev); | ||
966 | struct ax_device *ax = to_ax_dev(ndev); | ||
967 | |||
968 | ax_initial_setup(ndev, netdev_priv(ndev)); | ||
969 | ax_NS8390_init(ndev, ax->resume_open); | ||
970 | netif_device_attach(ndev); | ||
971 | |||
972 | if (ax->resume_open) | ||
973 | ax_open(ndev); | ||
974 | |||
975 | return 0; | ||
976 | } | ||
977 | |||
978 | #else | ||
979 | #define ax_suspend NULL | ||
980 | #define ax_resume NULL | ||
981 | #endif | ||
982 | |||
983 | static struct platform_driver axdrv = { | ||
984 | .driver = { | ||
985 | .name = "ax88796", | ||
986 | .owner = THIS_MODULE, | ||
987 | }, | ||
988 | .probe = ax_probe, | ||
989 | .remove = ax_remove, | ||
990 | .suspend = ax_suspend, | ||
991 | .resume = ax_resume, | ||
992 | }; | ||
993 | |||
994 | static int __init axdrv_init(void) | ||
995 | { | ||
996 | return platform_driver_register(&axdrv); | ||
997 | } | ||
998 | |||
999 | static void __exit axdrv_exit(void) | ||
1000 | { | ||
1001 | platform_driver_unregister(&axdrv); | ||
1002 | } | ||
1003 | |||
1004 | module_init(axdrv_init); | ||
1005 | module_exit(axdrv_exit); | ||
1006 | |||
1007 | MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver"); | ||
1008 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); | ||
1009 | MODULE_LICENSE("GPL v2"); | ||
1010 | MODULE_ALIAS("platform:ax88796"); | ||
diff --git a/drivers/net/ethernet/8390/axnet_cs.c b/drivers/net/ethernet/8390/axnet_cs.c new file mode 100644 index 000000000000..3e4b926c30dc --- /dev/null +++ b/drivers/net/ethernet/8390/axnet_cs.c | |||
@@ -0,0 +1,1725 @@ | |||
1 | /*====================================================================== | ||
2 | |||
3 | A PCMCIA ethernet driver for Asix AX88190-based cards | ||
4 | |||
5 | The Asix AX88190 is a NS8390-derived chipset with a few nasty | ||
6 | idiosyncracies that make it very inconvenient to support with a | ||
7 | standard 8390 driver. This driver is based on pcnet_cs, with the | ||
8 | tweaked 8390 code grafted on the end. Much of what I did was to | ||
9 | clean up and update a similar driver supplied by Asix, which was | ||
10 | adapted by William Lee, william@asix.com.tw. | ||
11 | |||
12 | Copyright (C) 2001 David A. Hinds -- dahinds@users.sourceforge.net | ||
13 | |||
14 | axnet_cs.c 1.28 2002/06/29 06:27:37 | ||
15 | |||
16 | The network driver code is based on Donald Becker's NE2000 code: | ||
17 | |||
18 | Written 1992,1993 by Donald Becker. | ||
19 | Copyright 1993 United States Government as represented by the | ||
20 | Director, National Security Agency. This software may be used and | ||
21 | distributed according to the terms of the GNU General Public License, | ||
22 | incorporated herein by reference. | ||
23 | Donald Becker may be reached at becker@scyld.com | ||
24 | |||
25 | ======================================================================*/ | ||
26 | |||
27 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
28 | |||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/ptrace.h> | ||
33 | #include <linux/string.h> | ||
34 | #include <linux/timer.h> | ||
35 | #include <linux/delay.h> | ||
36 | #include <linux/spinlock.h> | ||
37 | #include <linux/netdevice.h> | ||
38 | #include <linux/etherdevice.h> | ||
39 | #include <linux/crc32.h> | ||
40 | #include <linux/mii.h> | ||
41 | #include "8390.h" | ||
42 | |||
43 | #include <pcmcia/cistpl.h> | ||
44 | #include <pcmcia/ciscode.h> | ||
45 | #include <pcmcia/ds.h> | ||
46 | #include <pcmcia/cisreg.h> | ||
47 | |||
48 | #include <asm/io.h> | ||
49 | #include <asm/system.h> | ||
50 | #include <asm/byteorder.h> | ||
51 | #include <asm/uaccess.h> | ||
52 | |||
53 | #define AXNET_CMD 0x00 | ||
54 | #define AXNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */ | ||
55 | #define AXNET_RESET 0x1f /* Issue a read to reset, a write to clear. */ | ||
56 | #define AXNET_MII_EEP 0x14 /* Offset of MII access port */ | ||
57 | #define AXNET_TEST 0x15 /* Offset of TEST Register port */ | ||
58 | #define AXNET_GPIO 0x17 /* Offset of General Purpose Register Port */ | ||
59 | |||
60 | #define AXNET_START_PG 0x40 /* First page of TX buffer */ | ||
61 | #define AXNET_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
62 | |||
63 | #define AXNET_RDC_TIMEOUT 0x02 /* Max wait in jiffies for Tx RDC */ | ||
64 | |||
65 | #define IS_AX88190 0x0001 | ||
66 | #define IS_AX88790 0x0002 | ||
67 | |||
68 | /*====================================================================*/ | ||
69 | |||
70 | /* Module parameters */ | ||
71 | |||
72 | MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>"); | ||
73 | MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver"); | ||
74 | MODULE_LICENSE("GPL"); | ||
75 | |||
76 | |||
77 | /*====================================================================*/ | ||
78 | |||
79 | static int axnet_config(struct pcmcia_device *link); | ||
80 | static void axnet_release(struct pcmcia_device *link); | ||
81 | static int axnet_open(struct net_device *dev); | ||
82 | static int axnet_close(struct net_device *dev); | ||
83 | static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | ||
84 | static netdev_tx_t axnet_start_xmit(struct sk_buff *skb, | ||
85 | struct net_device *dev); | ||
86 | static struct net_device_stats *get_stats(struct net_device *dev); | ||
87 | static void set_multicast_list(struct net_device *dev); | ||
88 | static void axnet_tx_timeout(struct net_device *dev); | ||
89 | static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); | ||
90 | static void ei_watchdog(u_long arg); | ||
91 | static void axnet_reset_8390(struct net_device *dev); | ||
92 | |||
93 | static int mdio_read(unsigned int addr, int phy_id, int loc); | ||
94 | static void mdio_write(unsigned int addr, int phy_id, int loc, int value); | ||
95 | |||
96 | static void get_8390_hdr(struct net_device *, | ||
97 | struct e8390_pkt_hdr *, int); | ||
98 | static void block_input(struct net_device *dev, int count, | ||
99 | struct sk_buff *skb, int ring_offset); | ||
100 | static void block_output(struct net_device *dev, int count, | ||
101 | const u_char *buf, const int start_page); | ||
102 | |||
103 | static void axnet_detach(struct pcmcia_device *p_dev); | ||
104 | |||
105 | static void AX88190_init(struct net_device *dev, int startp); | ||
106 | static int ax_open(struct net_device *dev); | ||
107 | static int ax_close(struct net_device *dev); | ||
108 | static irqreturn_t ax_interrupt(int irq, void *dev_id); | ||
109 | |||
110 | /*====================================================================*/ | ||
111 | |||
112 | typedef struct axnet_dev_t { | ||
113 | struct pcmcia_device *p_dev; | ||
114 | caddr_t base; | ||
115 | struct timer_list watchdog; | ||
116 | int stale, fast_poll; | ||
117 | u_short link_status; | ||
118 | u_char duplex_flag; | ||
119 | int phy_id; | ||
120 | int flags; | ||
121 | int active_low; | ||
122 | } axnet_dev_t; | ||
123 | |||
124 | static inline axnet_dev_t *PRIV(struct net_device *dev) | ||
125 | { | ||
126 | void *p = (char *)netdev_priv(dev) + sizeof(struct ei_device); | ||
127 | return p; | ||
128 | } | ||
129 | |||
130 | static const struct net_device_ops axnet_netdev_ops = { | ||
131 | .ndo_open = axnet_open, | ||
132 | .ndo_stop = axnet_close, | ||
133 | .ndo_do_ioctl = axnet_ioctl, | ||
134 | .ndo_start_xmit = axnet_start_xmit, | ||
135 | .ndo_tx_timeout = axnet_tx_timeout, | ||
136 | .ndo_get_stats = get_stats, | ||
137 | .ndo_set_multicast_list = set_multicast_list, | ||
138 | .ndo_change_mtu = eth_change_mtu, | ||
139 | .ndo_set_mac_address = eth_mac_addr, | ||
140 | .ndo_validate_addr = eth_validate_addr, | ||
141 | }; | ||
142 | |||
143 | static int axnet_probe(struct pcmcia_device *link) | ||
144 | { | ||
145 | axnet_dev_t *info; | ||
146 | struct net_device *dev; | ||
147 | struct ei_device *ei_local; | ||
148 | |||
149 | dev_dbg(&link->dev, "axnet_attach()\n"); | ||
150 | |||
151 | dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(axnet_dev_t)); | ||
152 | if (!dev) | ||
153 | return -ENOMEM; | ||
154 | |||
155 | ei_local = netdev_priv(dev); | ||
156 | spin_lock_init(&ei_local->page_lock); | ||
157 | |||
158 | info = PRIV(dev); | ||
159 | info->p_dev = link; | ||
160 | link->priv = dev; | ||
161 | link->config_flags |= CONF_ENABLE_IRQ; | ||
162 | |||
163 | dev->netdev_ops = &axnet_netdev_ops; | ||
164 | |||
165 | dev->watchdog_timeo = TX_TIMEOUT; | ||
166 | |||
167 | return axnet_config(link); | ||
168 | } /* axnet_attach */ | ||
169 | |||
170 | static void axnet_detach(struct pcmcia_device *link) | ||
171 | { | ||
172 | struct net_device *dev = link->priv; | ||
173 | |||
174 | dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link); | ||
175 | |||
176 | unregister_netdev(dev); | ||
177 | |||
178 | axnet_release(link); | ||
179 | |||
180 | free_netdev(dev); | ||
181 | } /* axnet_detach */ | ||
182 | |||
183 | /*====================================================================== | ||
184 | |||
185 | This probes for a card's hardware address by reading the PROM. | ||
186 | |||
187 | ======================================================================*/ | ||
188 | |||
189 | static int get_prom(struct pcmcia_device *link) | ||
190 | { | ||
191 | struct net_device *dev = link->priv; | ||
192 | unsigned int ioaddr = dev->base_addr; | ||
193 | int i, j; | ||
194 | |||
195 | /* This is based on drivers/net/ne.c */ | ||
196 | struct { | ||
197 | u_char value, offset; | ||
198 | } program_seq[] = { | ||
199 | {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ | ||
200 | {0x01, EN0_DCFG}, /* Set word-wide access. */ | ||
201 | {0x00, EN0_RCNTLO}, /* Clear the count regs. */ | ||
202 | {0x00, EN0_RCNTHI}, | ||
203 | {0x00, EN0_IMR}, /* Mask completion irq. */ | ||
204 | {0xFF, EN0_ISR}, | ||
205 | {E8390_RXOFF|0x40, EN0_RXCR}, /* 0x60 Set to monitor */ | ||
206 | {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ | ||
207 | {0x10, EN0_RCNTLO}, | ||
208 | {0x00, EN0_RCNTHI}, | ||
209 | {0x00, EN0_RSARLO}, /* DMA starting at 0x0400. */ | ||
210 | {0x04, EN0_RSARHI}, | ||
211 | {E8390_RREAD+E8390_START, E8390_CMD}, | ||
212 | }; | ||
213 | |||
214 | /* Not much of a test, but the alternatives are messy */ | ||
215 | if (link->config_base != 0x03c0) | ||
216 | return 0; | ||
217 | |||
218 | axnet_reset_8390(dev); | ||
219 | mdelay(10); | ||
220 | |||
221 | for (i = 0; i < ARRAY_SIZE(program_seq); i++) | ||
222 | outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); | ||
223 | |||
224 | for (i = 0; i < 6; i += 2) { | ||
225 | j = inw(ioaddr + AXNET_DATAPORT); | ||
226 | dev->dev_addr[i] = j & 0xff; | ||
227 | dev->dev_addr[i+1] = j >> 8; | ||
228 | } | ||
229 | return 1; | ||
230 | } /* get_prom */ | ||
231 | |||
232 | static int try_io_port(struct pcmcia_device *link) | ||
233 | { | ||
234 | int j, ret; | ||
235 | link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; | ||
236 | link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH; | ||
237 | if (link->resource[0]->end == 32) { | ||
238 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; | ||
239 | /* for master/slave multifunction cards */ | ||
240 | if (link->resource[1]->end > 0) | ||
241 | link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; | ||
242 | } else { | ||
243 | /* This should be two 16-port windows */ | ||
244 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | ||
245 | link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16; | ||
246 | } | ||
247 | if (link->resource[0]->start == 0) { | ||
248 | for (j = 0; j < 0x400; j += 0x20) { | ||
249 | link->resource[0]->start = j ^ 0x300; | ||
250 | link->resource[1]->start = (j ^ 0x300) + 0x10; | ||
251 | link->io_lines = 16; | ||
252 | ret = pcmcia_request_io(link); | ||
253 | if (ret == 0) | ||
254 | return ret; | ||
255 | } | ||
256 | return ret; | ||
257 | } else { | ||
258 | return pcmcia_request_io(link); | ||
259 | } | ||
260 | } | ||
261 | |||
262 | static int axnet_configcheck(struct pcmcia_device *p_dev, void *priv_data) | ||
263 | { | ||
264 | if (p_dev->config_index == 0) | ||
265 | return -EINVAL; | ||
266 | |||
267 | p_dev->config_index = 0x05; | ||
268 | if (p_dev->resource[0]->end + p_dev->resource[1]->end < 32) | ||
269 | return -ENODEV; | ||
270 | |||
271 | return try_io_port(p_dev); | ||
272 | } | ||
273 | |||
274 | static int axnet_config(struct pcmcia_device *link) | ||
275 | { | ||
276 | struct net_device *dev = link->priv; | ||
277 | axnet_dev_t *info = PRIV(dev); | ||
278 | int i, j, j2, ret; | ||
279 | |||
280 | dev_dbg(&link->dev, "axnet_config(0x%p)\n", link); | ||
281 | |||
282 | /* don't trust the CIS on this; Linksys got it wrong */ | ||
283 | link->config_regs = 0x63; | ||
284 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; | ||
285 | ret = pcmcia_loop_config(link, axnet_configcheck, NULL); | ||
286 | if (ret != 0) | ||
287 | goto failed; | ||
288 | |||
289 | if (!link->irq) | ||
290 | goto failed; | ||
291 | |||
292 | if (resource_size(link->resource[1]) == 8) | ||
293 | link->config_flags |= CONF_ENABLE_SPKR; | ||
294 | |||
295 | ret = pcmcia_enable_device(link); | ||
296 | if (ret) | ||
297 | goto failed; | ||
298 | |||
299 | dev->irq = link->irq; | ||
300 | dev->base_addr = link->resource[0]->start; | ||
301 | |||
302 | if (!get_prom(link)) { | ||
303 | pr_notice("this is not an AX88190 card!\n"); | ||
304 | pr_notice("use pcnet_cs instead.\n"); | ||
305 | goto failed; | ||
306 | } | ||
307 | |||
308 | ei_status.name = "AX88190"; | ||
309 | ei_status.word16 = 1; | ||
310 | ei_status.tx_start_page = AXNET_START_PG; | ||
311 | ei_status.rx_start_page = AXNET_START_PG + TX_PAGES; | ||
312 | ei_status.stop_page = AXNET_STOP_PG; | ||
313 | ei_status.reset_8390 = axnet_reset_8390; | ||
314 | ei_status.get_8390_hdr = get_8390_hdr; | ||
315 | ei_status.block_input = block_input; | ||
316 | ei_status.block_output = block_output; | ||
317 | |||
318 | if (inb(dev->base_addr + AXNET_TEST) != 0) | ||
319 | info->flags |= IS_AX88790; | ||
320 | else | ||
321 | info->flags |= IS_AX88190; | ||
322 | |||
323 | if (info->flags & IS_AX88790) | ||
324 | outb(0x10, dev->base_addr + AXNET_GPIO); /* select Internal PHY */ | ||
325 | |||
326 | info->active_low = 0; | ||
327 | |||
328 | for (i = 0; i < 32; i++) { | ||
329 | j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1); | ||
330 | j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2); | ||
331 | if (j == j2) continue; | ||
332 | if ((j != 0) && (j != 0xffff)) break; | ||
333 | } | ||
334 | |||
335 | if (i == 32) { | ||
336 | /* Maybe PHY is in power down mode. (PPD_SET = 1) | ||
337 | Bit 2 of CCSR is active low. */ | ||
338 | pcmcia_write_config_byte(link, CISREG_CCSR, 0x04); | ||
339 | for (i = 0; i < 32; i++) { | ||
340 | j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1); | ||
341 | j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2); | ||
342 | if (j == j2) continue; | ||
343 | if ((j != 0) && (j != 0xffff)) { | ||
344 | info->active_low = 1; | ||
345 | break; | ||
346 | } | ||
347 | } | ||
348 | } | ||
349 | |||
350 | info->phy_id = (i < 32) ? i : -1; | ||
351 | SET_NETDEV_DEV(dev, &link->dev); | ||
352 | |||
353 | if (register_netdev(dev) != 0) { | ||
354 | pr_notice("register_netdev() failed\n"); | ||
355 | goto failed; | ||
356 | } | ||
357 | |||
358 | netdev_info(dev, "Asix AX88%d90: io %#3lx, irq %d, hw_addr %pM\n", | ||
359 | ((info->flags & IS_AX88790) ? 7 : 1), | ||
360 | dev->base_addr, dev->irq, dev->dev_addr); | ||
361 | if (info->phy_id != -1) { | ||
362 | netdev_dbg(dev, " MII transceiver at index %d, status %x\n", | ||
363 | info->phy_id, j); | ||
364 | } else { | ||
365 | netdev_notice(dev, " No MII transceivers found!\n"); | ||
366 | } | ||
367 | return 0; | ||
368 | |||
369 | failed: | ||
370 | axnet_release(link); | ||
371 | return -ENODEV; | ||
372 | } /* axnet_config */ | ||
373 | |||
374 | static void axnet_release(struct pcmcia_device *link) | ||
375 | { | ||
376 | pcmcia_disable_device(link); | ||
377 | } | ||
378 | |||
379 | static int axnet_suspend(struct pcmcia_device *link) | ||
380 | { | ||
381 | struct net_device *dev = link->priv; | ||
382 | |||
383 | if (link->open) | ||
384 | netif_device_detach(dev); | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static int axnet_resume(struct pcmcia_device *link) | ||
390 | { | ||
391 | struct net_device *dev = link->priv; | ||
392 | axnet_dev_t *info = PRIV(dev); | ||
393 | |||
394 | if (link->open) { | ||
395 | if (info->active_low == 1) | ||
396 | pcmcia_write_config_byte(link, CISREG_CCSR, 0x04); | ||
397 | |||
398 | axnet_reset_8390(dev); | ||
399 | AX88190_init(dev, 1); | ||
400 | netif_device_attach(dev); | ||
401 | } | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | |||
407 | /*====================================================================== | ||
408 | |||
409 | MII interface support | ||
410 | |||
411 | ======================================================================*/ | ||
412 | |||
413 | #define MDIO_SHIFT_CLK 0x01 | ||
414 | #define MDIO_DATA_WRITE0 0x00 | ||
415 | #define MDIO_DATA_WRITE1 0x08 | ||
416 | #define MDIO_DATA_READ 0x04 | ||
417 | #define MDIO_MASK 0x0f | ||
418 | #define MDIO_ENB_IN 0x02 | ||
419 | |||
420 | static void mdio_sync(unsigned int addr) | ||
421 | { | ||
422 | int bits; | ||
423 | for (bits = 0; bits < 32; bits++) { | ||
424 | outb_p(MDIO_DATA_WRITE1, addr); | ||
425 | outb_p(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, addr); | ||
426 | } | ||
427 | } | ||
428 | |||
429 | static int mdio_read(unsigned int addr, int phy_id, int loc) | ||
430 | { | ||
431 | u_int cmd = (0xf6<<10)|(phy_id<<5)|loc; | ||
432 | int i, retval = 0; | ||
433 | |||
434 | mdio_sync(addr); | ||
435 | for (i = 14; i >= 0; i--) { | ||
436 | int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0; | ||
437 | outb_p(dat, addr); | ||
438 | outb_p(dat | MDIO_SHIFT_CLK, addr); | ||
439 | } | ||
440 | for (i = 19; i > 0; i--) { | ||
441 | outb_p(MDIO_ENB_IN, addr); | ||
442 | retval = (retval << 1) | ((inb_p(addr) & MDIO_DATA_READ) != 0); | ||
443 | outb_p(MDIO_ENB_IN | MDIO_SHIFT_CLK, addr); | ||
444 | } | ||
445 | return (retval>>1) & 0xffff; | ||
446 | } | ||
447 | |||
448 | static void mdio_write(unsigned int addr, int phy_id, int loc, int value) | ||
449 | { | ||
450 | u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value; | ||
451 | int i; | ||
452 | |||
453 | mdio_sync(addr); | ||
454 | for (i = 31; i >= 0; i--) { | ||
455 | int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0; | ||
456 | outb_p(dat, addr); | ||
457 | outb_p(dat | MDIO_SHIFT_CLK, addr); | ||
458 | } | ||
459 | for (i = 1; i >= 0; i--) { | ||
460 | outb_p(MDIO_ENB_IN, addr); | ||
461 | outb_p(MDIO_ENB_IN | MDIO_SHIFT_CLK, addr); | ||
462 | } | ||
463 | } | ||
464 | |||
465 | /*====================================================================*/ | ||
466 | |||
467 | static int axnet_open(struct net_device *dev) | ||
468 | { | ||
469 | int ret; | ||
470 | axnet_dev_t *info = PRIV(dev); | ||
471 | struct pcmcia_device *link = info->p_dev; | ||
472 | unsigned int nic_base = dev->base_addr; | ||
473 | |||
474 | dev_dbg(&link->dev, "axnet_open('%s')\n", dev->name); | ||
475 | |||
476 | if (!pcmcia_dev_present(link)) | ||
477 | return -ENODEV; | ||
478 | |||
479 | outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */ | ||
480 | ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, "axnet_cs", dev); | ||
481 | if (ret) | ||
482 | return ret; | ||
483 | |||
484 | link->open++; | ||
485 | |||
486 | info->link_status = 0x00; | ||
487 | init_timer(&info->watchdog); | ||
488 | info->watchdog.function = ei_watchdog; | ||
489 | info->watchdog.data = (u_long)dev; | ||
490 | info->watchdog.expires = jiffies + HZ; | ||
491 | add_timer(&info->watchdog); | ||
492 | |||
493 | return ax_open(dev); | ||
494 | } /* axnet_open */ | ||
495 | |||
496 | /*====================================================================*/ | ||
497 | |||
498 | static int axnet_close(struct net_device *dev) | ||
499 | { | ||
500 | axnet_dev_t *info = PRIV(dev); | ||
501 | struct pcmcia_device *link = info->p_dev; | ||
502 | |||
503 | dev_dbg(&link->dev, "axnet_close('%s')\n", dev->name); | ||
504 | |||
505 | ax_close(dev); | ||
506 | free_irq(dev->irq, dev); | ||
507 | |||
508 | link->open--; | ||
509 | netif_stop_queue(dev); | ||
510 | del_timer_sync(&info->watchdog); | ||
511 | |||
512 | return 0; | ||
513 | } /* axnet_close */ | ||
514 | |||
515 | /*====================================================================== | ||
516 | |||
517 | Hard reset the card. This used to pause for the same period that | ||
518 | a 8390 reset command required, but that shouldn't be necessary. | ||
519 | |||
520 | ======================================================================*/ | ||
521 | |||
522 | static void axnet_reset_8390(struct net_device *dev) | ||
523 | { | ||
524 | unsigned int nic_base = dev->base_addr; | ||
525 | int i; | ||
526 | |||
527 | ei_status.txing = ei_status.dmaing = 0; | ||
528 | |||
529 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, nic_base + E8390_CMD); | ||
530 | |||
531 | outb(inb(nic_base + AXNET_RESET), nic_base + AXNET_RESET); | ||
532 | |||
533 | for (i = 0; i < 100; i++) { | ||
534 | if ((inb_p(nic_base+EN0_ISR) & ENISR_RESET) != 0) | ||
535 | break; | ||
536 | udelay(100); | ||
537 | } | ||
538 | outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */ | ||
539 | |||
540 | if (i == 100) | ||
541 | netdev_err(dev, "axnet_reset_8390() did not complete\n"); | ||
542 | |||
543 | } /* axnet_reset_8390 */ | ||
544 | |||
545 | /*====================================================================*/ | ||
546 | |||
547 | static irqreturn_t ei_irq_wrapper(int irq, void *dev_id) | ||
548 | { | ||
549 | struct net_device *dev = dev_id; | ||
550 | PRIV(dev)->stale = 0; | ||
551 | return ax_interrupt(irq, dev_id); | ||
552 | } | ||
553 | |||
554 | static void ei_watchdog(u_long arg) | ||
555 | { | ||
556 | struct net_device *dev = (struct net_device *)(arg); | ||
557 | axnet_dev_t *info = PRIV(dev); | ||
558 | unsigned int nic_base = dev->base_addr; | ||
559 | unsigned int mii_addr = nic_base + AXNET_MII_EEP; | ||
560 | u_short link; | ||
561 | |||
562 | if (!netif_device_present(dev)) goto reschedule; | ||
563 | |||
564 | /* Check for pending interrupt with expired latency timer: with | ||
565 | this, we can limp along even if the interrupt is blocked */ | ||
566 | if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) { | ||
567 | if (!info->fast_poll) | ||
568 | netdev_info(dev, "interrupt(s) dropped!\n"); | ||
569 | ei_irq_wrapper(dev->irq, dev); | ||
570 | info->fast_poll = HZ; | ||
571 | } | ||
572 | if (info->fast_poll) { | ||
573 | info->fast_poll--; | ||
574 | info->watchdog.expires = jiffies + 1; | ||
575 | add_timer(&info->watchdog); | ||
576 | return; | ||
577 | } | ||
578 | |||
579 | if (info->phy_id < 0) | ||
580 | goto reschedule; | ||
581 | link = mdio_read(mii_addr, info->phy_id, 1); | ||
582 | if (!link || (link == 0xffff)) { | ||
583 | netdev_info(dev, "MII is missing!\n"); | ||
584 | info->phy_id = -1; | ||
585 | goto reschedule; | ||
586 | } | ||
587 | |||
588 | link &= 0x0004; | ||
589 | if (link != info->link_status) { | ||
590 | u_short p = mdio_read(mii_addr, info->phy_id, 5); | ||
591 | netdev_info(dev, "%s link beat\n", link ? "found" : "lost"); | ||
592 | if (link) { | ||
593 | info->duplex_flag = (p & 0x0140) ? 0x80 : 0x00; | ||
594 | if (p) | ||
595 | netdev_info(dev, "autonegotiation complete: %dbaseT-%cD selected\n", | ||
596 | (p & 0x0180) ? 100 : 10, (p & 0x0140) ? 'F' : 'H'); | ||
597 | else | ||
598 | netdev_info(dev, "link partner did not autonegotiate\n"); | ||
599 | AX88190_init(dev, 1); | ||
600 | } | ||
601 | info->link_status = link; | ||
602 | } | ||
603 | |||
604 | reschedule: | ||
605 | info->watchdog.expires = jiffies + HZ; | ||
606 | add_timer(&info->watchdog); | ||
607 | } | ||
608 | |||
609 | /*====================================================================*/ | ||
610 | |||
611 | static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | ||
612 | { | ||
613 | axnet_dev_t *info = PRIV(dev); | ||
614 | struct mii_ioctl_data *data = if_mii(rq); | ||
615 | unsigned int mii_addr = dev->base_addr + AXNET_MII_EEP; | ||
616 | switch (cmd) { | ||
617 | case SIOCGMIIPHY: | ||
618 | data->phy_id = info->phy_id; | ||
619 | case SIOCGMIIREG: /* Read MII PHY register. */ | ||
620 | data->val_out = mdio_read(mii_addr, data->phy_id, data->reg_num & 0x1f); | ||
621 | return 0; | ||
622 | case SIOCSMIIREG: /* Write MII PHY register. */ | ||
623 | mdio_write(mii_addr, data->phy_id, data->reg_num & 0x1f, data->val_in); | ||
624 | return 0; | ||
625 | } | ||
626 | return -EOPNOTSUPP; | ||
627 | } | ||
628 | |||
629 | /*====================================================================*/ | ||
630 | |||
631 | static void get_8390_hdr(struct net_device *dev, | ||
632 | struct e8390_pkt_hdr *hdr, | ||
633 | int ring_page) | ||
634 | { | ||
635 | unsigned int nic_base = dev->base_addr; | ||
636 | |||
637 | outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ | ||
638 | outb_p(ring_page, nic_base + EN0_RSARHI); | ||
639 | outb_p(E8390_RREAD+E8390_START, nic_base + AXNET_CMD); | ||
640 | |||
641 | insw(nic_base + AXNET_DATAPORT, hdr, | ||
642 | sizeof(struct e8390_pkt_hdr)>>1); | ||
643 | /* Fix for big endian systems */ | ||
644 | hdr->count = le16_to_cpu(hdr->count); | ||
645 | |||
646 | } | ||
647 | |||
648 | /*====================================================================*/ | ||
649 | |||
650 | static void block_input(struct net_device *dev, int count, | ||
651 | struct sk_buff *skb, int ring_offset) | ||
652 | { | ||
653 | unsigned int nic_base = dev->base_addr; | ||
654 | int xfer_count = count; | ||
655 | char *buf = skb->data; | ||
656 | |||
657 | if ((ei_debug > 4) && (count != 4)) | ||
658 | pr_debug("%s: [bi=%d]\n", dev->name, count+4); | ||
659 | outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); | ||
660 | outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); | ||
661 | outb_p(E8390_RREAD+E8390_START, nic_base + AXNET_CMD); | ||
662 | |||
663 | insw(nic_base + AXNET_DATAPORT,buf,count>>1); | ||
664 | if (count & 0x01) | ||
665 | buf[count-1] = inb(nic_base + AXNET_DATAPORT), xfer_count++; | ||
666 | |||
667 | } | ||
668 | |||
669 | /*====================================================================*/ | ||
670 | |||
671 | static void block_output(struct net_device *dev, int count, | ||
672 | const u_char *buf, const int start_page) | ||
673 | { | ||
674 | unsigned int nic_base = dev->base_addr; | ||
675 | |||
676 | pr_debug("%s: [bo=%d]\n", dev->name, count); | ||
677 | |||
678 | /* Round the count up for word writes. Do we need to do this? | ||
679 | What effect will an odd byte count have on the 8390? | ||
680 | I should check someday. */ | ||
681 | if (count & 0x01) | ||
682 | count++; | ||
683 | |||
684 | outb_p(0x00, nic_base + EN0_RSARLO); | ||
685 | outb_p(start_page, nic_base + EN0_RSARHI); | ||
686 | outb_p(E8390_RWRITE+E8390_START, nic_base + AXNET_CMD); | ||
687 | outsw(nic_base + AXNET_DATAPORT, buf, count>>1); | ||
688 | } | ||
689 | |||
690 | static const struct pcmcia_device_id axnet_ids[] = { | ||
691 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081), | ||
692 | PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301), | ||
693 | PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328), | ||
694 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0301), | ||
695 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0303), | ||
696 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309), | ||
697 | PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1106), | ||
698 | PCMCIA_DEVICE_MANF_CARD(0x8a01, 0xc1ab), | ||
699 | PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), | ||
700 | PCMCIA_DEVICE_MANF_CARD(0xffff, 0x1090), | ||
701 | PCMCIA_DEVICE_PROD_ID12("AmbiCom,Inc.", "Fast Ethernet PC Card(AMB8110)", 0x49b020a7, 0x119cc9fc), | ||
702 | PCMCIA_DEVICE_PROD_ID124("Fast Ethernet", "16-bit PC Card", "AX88190", 0xb4be14e3, 0x9a12eb6a, 0xab9be5ef), | ||
703 | PCMCIA_DEVICE_PROD_ID12("ASIX", "AX88190", 0x0959823b, 0xab9be5ef), | ||
704 | PCMCIA_DEVICE_PROD_ID12("Billionton", "LNA-100B", 0x552ab682, 0xbc3b87e1), | ||
705 | PCMCIA_DEVICE_PROD_ID12("CHEETAH ETHERCARD", "EN2228", 0x00fa7bc8, 0x00e990cc), | ||
706 | PCMCIA_DEVICE_PROD_ID12("CNet", "CNF301", 0xbc477dde, 0x78c5f40b), | ||
707 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXD", 0x5261440f, 0x436768c5), | ||
708 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEtherII PCC-TXD", 0x5261440f, 0x730df72e), | ||
709 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FEther PCC-TXM", 0x5261440f, 0x3abbd061), | ||
710 | PCMCIA_DEVICE_PROD_ID12("Dynalink", "L100C16", 0x55632fd5, 0x66bc2a90), | ||
711 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "ETXPCM", 0x547e66dc, 0x233adac2), | ||
712 | PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V3)", 0x0733cc81, 0x232019a8), | ||
713 | PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC3-TX", 0x481e0094, 0xf91af609), | ||
714 | PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA411", 0x9aa79dc3, 0x40fad875), | ||
715 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "100BASE", 0x281f1c5d, 0x7c2add04), | ||
716 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEtherCard", 0x281f1c5d, 0x7ef26116), | ||
717 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FEP501", 0x281f1c5d, 0x2e272058), | ||
718 | PCMCIA_DEVICE_PROD_ID14("Network Everywhere", "AX88190", 0x820a67b6, 0xab9be5ef), | ||
719 | PCMCIA_DEVICE_NULL, | ||
720 | }; | ||
721 | MODULE_DEVICE_TABLE(pcmcia, axnet_ids); | ||
722 | |||
723 | static struct pcmcia_driver axnet_cs_driver = { | ||
724 | .owner = THIS_MODULE, | ||
725 | .name = "axnet_cs", | ||
726 | .probe = axnet_probe, | ||
727 | .remove = axnet_detach, | ||
728 | .id_table = axnet_ids, | ||
729 | .suspend = axnet_suspend, | ||
730 | .resume = axnet_resume, | ||
731 | }; | ||
732 | |||
733 | static int __init init_axnet_cs(void) | ||
734 | { | ||
735 | return pcmcia_register_driver(&axnet_cs_driver); | ||
736 | } | ||
737 | |||
738 | static void __exit exit_axnet_cs(void) | ||
739 | { | ||
740 | pcmcia_unregister_driver(&axnet_cs_driver); | ||
741 | } | ||
742 | |||
743 | module_init(init_axnet_cs); | ||
744 | module_exit(exit_axnet_cs); | ||
745 | |||
746 | /*====================================================================*/ | ||
747 | |||
748 | /* 8390.c: A general NS8390 ethernet driver core for linux. */ | ||
749 | /* | ||
750 | Written 1992-94 by Donald Becker. | ||
751 | |||
752 | Copyright 1993 United States Government as represented by the | ||
753 | Director, National Security Agency. | ||
754 | |||
755 | This software may be used and distributed according to the terms | ||
756 | of the GNU General Public License, incorporated herein by reference. | ||
757 | |||
758 | The author may be reached as becker@scyld.com, or C/O | ||
759 | Scyld Computing Corporation | ||
760 | 410 Severn Ave., Suite 210 | ||
761 | Annapolis MD 21403 | ||
762 | |||
763 | This is the chip-specific code for many 8390-based ethernet adaptors. | ||
764 | This is not a complete driver, it must be combined with board-specific | ||
765 | code such as ne.c, wd.c, 3c503.c, etc. | ||
766 | |||
767 | Seeing how at least eight drivers use this code, (not counting the | ||
768 | PCMCIA ones either) it is easy to break some card by what seems like | ||
769 | a simple innocent change. Please contact me or Donald if you think | ||
770 | you have found something that needs changing. -- PG | ||
771 | |||
772 | Changelog: | ||
773 | |||
774 | Paul Gortmaker : remove set_bit lock, other cleanups. | ||
775 | Paul Gortmaker : add ei_get_8390_hdr() so we can pass skb's to | ||
776 | ei_block_input() for eth_io_copy_and_sum(). | ||
777 | Paul Gortmaker : exchange static int ei_pingpong for a #define, | ||
778 | also add better Tx error handling. | ||
779 | Paul Gortmaker : rewrite Rx overrun handling as per NS specs. | ||
780 | Alexey Kuznetsov : use the 8390's six bit hash multicast filter. | ||
781 | Paul Gortmaker : tweak ANK's above multicast changes a bit. | ||
782 | Paul Gortmaker : update packet statistics for v2.1.x | ||
783 | Alan Cox : support arbitrary stupid port mappings on the | ||
784 | 68K Macintosh. Support >16bit I/O spaces | ||
785 | Paul Gortmaker : add kmod support for auto-loading of the 8390 | ||
786 | module by all drivers that require it. | ||
787 | Alan Cox : Spinlocking work, added 'BUG_83C690' | ||
788 | Paul Gortmaker : Separate out Tx timeout code from Tx path. | ||
789 | |||
790 | Sources: | ||
791 | The National Semiconductor LAN Databook, and the 3Com 3c503 databook. | ||
792 | |||
793 | */ | ||
794 | |||
795 | #include <linux/bitops.h> | ||
796 | #include <asm/irq.h> | ||
797 | #include <linux/fcntl.h> | ||
798 | #include <linux/in.h> | ||
799 | #include <linux/interrupt.h> | ||
800 | |||
801 | #define BUG_83C690 | ||
802 | |||
803 | /* These are the operational function interfaces to board-specific | ||
804 | routines. | ||
805 | void reset_8390(struct net_device *dev) | ||
806 | Resets the board associated with DEV, including a hardware reset of | ||
807 | the 8390. This is only called when there is a transmit timeout, and | ||
808 | it is always followed by 8390_init(). | ||
809 | void block_output(struct net_device *dev, int count, const unsigned char *buf, | ||
810 | int start_page) | ||
811 | Write the COUNT bytes of BUF to the packet buffer at START_PAGE. The | ||
812 | "page" value uses the 8390's 256-byte pages. | ||
813 | void get_8390_hdr(struct net_device *dev, struct e8390_hdr *hdr, int ring_page) | ||
814 | Read the 4 byte, page aligned 8390 header. *If* there is a | ||
815 | subsequent read, it will be of the rest of the packet. | ||
816 | void block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
817 | Read COUNT bytes from the packet buffer into the skb data area. Start | ||
818 | reading from RING_OFFSET, the address as the 8390 sees it. This will always | ||
819 | follow the read of the 8390 header. | ||
820 | */ | ||
821 | #define ei_reset_8390 (ei_local->reset_8390) | ||
822 | #define ei_block_output (ei_local->block_output) | ||
823 | #define ei_block_input (ei_local->block_input) | ||
824 | #define ei_get_8390_hdr (ei_local->get_8390_hdr) | ||
825 | |||
826 | /* use 0 for production, 1 for verification, >2 for debug */ | ||
827 | #ifndef ei_debug | ||
828 | int ei_debug = 1; | ||
829 | #endif | ||
830 | |||
831 | /* Index to functions. */ | ||
832 | static void ei_tx_intr(struct net_device *dev); | ||
833 | static void ei_tx_err(struct net_device *dev); | ||
834 | static void ei_receive(struct net_device *dev); | ||
835 | static void ei_rx_overrun(struct net_device *dev); | ||
836 | |||
837 | /* Routines generic to NS8390-based boards. */ | ||
838 | static void NS8390_trigger_send(struct net_device *dev, unsigned int length, | ||
839 | int start_page); | ||
840 | static void do_set_multicast_list(struct net_device *dev); | ||
841 | |||
842 | /* | ||
843 | * SMP and the 8390 setup. | ||
844 | * | ||
845 | * The 8390 isn't exactly designed to be multithreaded on RX/TX. There is | ||
846 | * a page register that controls bank and packet buffer access. We guard | ||
847 | * this with ei_local->page_lock. Nobody should assume or set the page other | ||
848 | * than zero when the lock is not held. Lock holders must restore page 0 | ||
849 | * before unlocking. Even pure readers must take the lock to protect in | ||
850 | * page 0. | ||
851 | * | ||
852 | * To make life difficult the chip can also be very slow. We therefore can't | ||
853 | * just use spinlocks. For the longer lockups we disable the irq the device | ||
854 | * sits on and hold the lock. We must hold the lock because there is a dual | ||
855 | * processor case other than interrupts (get stats/set multicast list in | ||
856 | * parallel with each other and transmit). | ||
857 | * | ||
858 | * Note: in theory we can just disable the irq on the card _but_ there is | ||
859 | * a latency on SMP irq delivery. So we can easily go "disable irq" "sync irqs" | ||
860 | * enter lock, take the queued irq. So we waddle instead of flying. | ||
861 | * | ||
862 | * Finally by special arrangement for the purpose of being generally | ||
863 | * annoying the transmit function is called bh atomic. That places | ||
864 | * restrictions on the user context callers as disable_irq won't save | ||
865 | * them. | ||
866 | */ | ||
867 | |||
868 | /** | ||
869 | * ax_open - Open/initialize the board. | ||
870 | * @dev: network device to initialize | ||
871 | * | ||
872 | * This routine goes all-out, setting everything | ||
873 | * up anew at each open, even though many of these registers should only | ||
874 | * need to be set once at boot. | ||
875 | */ | ||
876 | static int ax_open(struct net_device *dev) | ||
877 | { | ||
878 | unsigned long flags; | ||
879 | struct ei_device *ei_local = netdev_priv(dev); | ||
880 | |||
881 | /* | ||
882 | * Grab the page lock so we own the register set, then call | ||
883 | * the init function. | ||
884 | */ | ||
885 | |||
886 | spin_lock_irqsave(&ei_local->page_lock, flags); | ||
887 | AX88190_init(dev, 1); | ||
888 | /* Set the flag before we drop the lock, That way the IRQ arrives | ||
889 | after its set and we get no silly warnings */ | ||
890 | netif_start_queue(dev); | ||
891 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
892 | ei_local->irqlock = 0; | ||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | #define dev_lock(dev) (((struct ei_device *)netdev_priv(dev))->page_lock) | ||
897 | |||
898 | /** | ||
899 | * ax_close - shut down network device | ||
900 | * @dev: network device to close | ||
901 | * | ||
902 | * Opposite of ax_open(). Only used when "ifconfig <devname> down" is done. | ||
903 | */ | ||
904 | static int ax_close(struct net_device *dev) | ||
905 | { | ||
906 | unsigned long flags; | ||
907 | |||
908 | /* | ||
909 | * Hold the page lock during close | ||
910 | */ | ||
911 | |||
912 | spin_lock_irqsave(&dev_lock(dev), flags); | ||
913 | AX88190_init(dev, 0); | ||
914 | spin_unlock_irqrestore(&dev_lock(dev), flags); | ||
915 | netif_stop_queue(dev); | ||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | /** | ||
920 | * axnet_tx_timeout - handle transmit time out condition | ||
921 | * @dev: network device which has apparently fallen asleep | ||
922 | * | ||
923 | * Called by kernel when device never acknowledges a transmit has | ||
924 | * completed (or failed) - i.e. never posted a Tx related interrupt. | ||
925 | */ | ||
926 | |||
927 | static void axnet_tx_timeout(struct net_device *dev) | ||
928 | { | ||
929 | long e8390_base = dev->base_addr; | ||
930 | struct ei_device *ei_local = netdev_priv(dev); | ||
931 | int txsr, isr, tickssofar = jiffies - dev_trans_start(dev); | ||
932 | unsigned long flags; | ||
933 | |||
934 | dev->stats.tx_errors++; | ||
935 | |||
936 | spin_lock_irqsave(&ei_local->page_lock, flags); | ||
937 | txsr = inb(e8390_base+EN0_TSR); | ||
938 | isr = inb(e8390_base+EN0_ISR); | ||
939 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
940 | |||
941 | netdev_printk(KERN_DEBUG, dev, | ||
942 | "Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n", | ||
943 | (txsr & ENTSR_ABT) ? "excess collisions." : | ||
944 | (isr) ? "lost interrupt?" : "cable problem?", | ||
945 | txsr, isr, tickssofar); | ||
946 | |||
947 | if (!isr && !dev->stats.tx_packets) | ||
948 | { | ||
949 | /* The 8390 probably hasn't gotten on the cable yet. */ | ||
950 | ei_local->interface_num ^= 1; /* Try a different xcvr. */ | ||
951 | } | ||
952 | |||
953 | /* Ugly but a reset can be slow, yet must be protected */ | ||
954 | |||
955 | spin_lock_irqsave(&ei_local->page_lock, flags); | ||
956 | |||
957 | /* Try to restart the card. Perhaps the user has fixed something. */ | ||
958 | ei_reset_8390(dev); | ||
959 | AX88190_init(dev, 1); | ||
960 | |||
961 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
962 | netif_wake_queue(dev); | ||
963 | } | ||
964 | |||
965 | /** | ||
966 | * axnet_start_xmit - begin packet transmission | ||
967 | * @skb: packet to be sent | ||
968 | * @dev: network device to which packet is sent | ||
969 | * | ||
970 | * Sends a packet to an 8390 network device. | ||
971 | */ | ||
972 | |||
973 | static netdev_tx_t axnet_start_xmit(struct sk_buff *skb, | ||
974 | struct net_device *dev) | ||
975 | { | ||
976 | long e8390_base = dev->base_addr; | ||
977 | struct ei_device *ei_local = netdev_priv(dev); | ||
978 | int length, send_length, output_page; | ||
979 | unsigned long flags; | ||
980 | u8 packet[ETH_ZLEN]; | ||
981 | |||
982 | netif_stop_queue(dev); | ||
983 | |||
984 | length = skb->len; | ||
985 | |||
986 | /* Mask interrupts from the ethercard. | ||
987 | SMP: We have to grab the lock here otherwise the IRQ handler | ||
988 | on another CPU can flip window and race the IRQ mask set. We end | ||
989 | up trashing the mcast filter not disabling irqs if we don't lock */ | ||
990 | |||
991 | spin_lock_irqsave(&ei_local->page_lock, flags); | ||
992 | outb_p(0x00, e8390_base + EN0_IMR); | ||
993 | |||
994 | /* | ||
995 | * Slow phase with lock held. | ||
996 | */ | ||
997 | |||
998 | ei_local->irqlock = 1; | ||
999 | |||
1000 | send_length = max(length, ETH_ZLEN); | ||
1001 | |||
1002 | /* | ||
1003 | * We have two Tx slots available for use. Find the first free | ||
1004 | * slot, and then perform some sanity checks. With two Tx bufs, | ||
1005 | * you get very close to transmitting back-to-back packets. With | ||
1006 | * only one Tx buf, the transmitter sits idle while you reload the | ||
1007 | * card, leaving a substantial gap between each transmitted packet. | ||
1008 | */ | ||
1009 | |||
1010 | if (ei_local->tx1 == 0) | ||
1011 | { | ||
1012 | output_page = ei_local->tx_start_page; | ||
1013 | ei_local->tx1 = send_length; | ||
1014 | if (ei_debug && ei_local->tx2 > 0) | ||
1015 | netdev_printk(KERN_DEBUG, dev, | ||
1016 | "idle transmitter tx2=%d, lasttx=%d, txing=%d\n", | ||
1017 | ei_local->tx2, ei_local->lasttx, | ||
1018 | ei_local->txing); | ||
1019 | } | ||
1020 | else if (ei_local->tx2 == 0) | ||
1021 | { | ||
1022 | output_page = ei_local->tx_start_page + TX_PAGES/2; | ||
1023 | ei_local->tx2 = send_length; | ||
1024 | if (ei_debug && ei_local->tx1 > 0) | ||
1025 | netdev_printk(KERN_DEBUG, dev, | ||
1026 | "idle transmitter, tx1=%d, lasttx=%d, txing=%d\n", | ||
1027 | ei_local->tx1, ei_local->lasttx, | ||
1028 | ei_local->txing); | ||
1029 | } | ||
1030 | else | ||
1031 | { /* We should never get here. */ | ||
1032 | if (ei_debug) | ||
1033 | netdev_printk(KERN_DEBUG, dev, | ||
1034 | "No Tx buffers free! tx1=%d tx2=%d last=%d\n", | ||
1035 | ei_local->tx1, ei_local->tx2, | ||
1036 | ei_local->lasttx); | ||
1037 | ei_local->irqlock = 0; | ||
1038 | netif_stop_queue(dev); | ||
1039 | outb_p(ENISR_ALL, e8390_base + EN0_IMR); | ||
1040 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
1041 | dev->stats.tx_errors++; | ||
1042 | return NETDEV_TX_BUSY; | ||
1043 | } | ||
1044 | |||
1045 | /* | ||
1046 | * Okay, now upload the packet and trigger a send if the transmitter | ||
1047 | * isn't already sending. If it is busy, the interrupt handler will | ||
1048 | * trigger the send later, upon receiving a Tx done interrupt. | ||
1049 | */ | ||
1050 | |||
1051 | if (length == skb->len) | ||
1052 | ei_block_output(dev, length, skb->data, output_page); | ||
1053 | else { | ||
1054 | memset(packet, 0, ETH_ZLEN); | ||
1055 | skb_copy_from_linear_data(skb, packet, skb->len); | ||
1056 | ei_block_output(dev, length, packet, output_page); | ||
1057 | } | ||
1058 | |||
1059 | if (! ei_local->txing) | ||
1060 | { | ||
1061 | ei_local->txing = 1; | ||
1062 | NS8390_trigger_send(dev, send_length, output_page); | ||
1063 | dev->trans_start = jiffies; | ||
1064 | if (output_page == ei_local->tx_start_page) | ||
1065 | { | ||
1066 | ei_local->tx1 = -1; | ||
1067 | ei_local->lasttx = -1; | ||
1068 | } | ||
1069 | else | ||
1070 | { | ||
1071 | ei_local->tx2 = -1; | ||
1072 | ei_local->lasttx = -2; | ||
1073 | } | ||
1074 | } | ||
1075 | else ei_local->txqueue++; | ||
1076 | |||
1077 | if (ei_local->tx1 && ei_local->tx2) | ||
1078 | netif_stop_queue(dev); | ||
1079 | else | ||
1080 | netif_start_queue(dev); | ||
1081 | |||
1082 | /* Turn 8390 interrupts back on. */ | ||
1083 | ei_local->irqlock = 0; | ||
1084 | outb_p(ENISR_ALL, e8390_base + EN0_IMR); | ||
1085 | |||
1086 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
1087 | |||
1088 | dev_kfree_skb (skb); | ||
1089 | dev->stats.tx_bytes += send_length; | ||
1090 | |||
1091 | return NETDEV_TX_OK; | ||
1092 | } | ||
1093 | |||
1094 | /** | ||
1095 | * ax_interrupt - handle the interrupts from an 8390 | ||
1096 | * @irq: interrupt number | ||
1097 | * @dev_id: a pointer to the net_device | ||
1098 | * | ||
1099 | * Handle the ether interface interrupts. We pull packets from | ||
1100 | * the 8390 via the card specific functions and fire them at the networking | ||
1101 | * stack. We also handle transmit completions and wake the transmit path if | ||
1102 | * necessary. We also update the counters and do other housekeeping as | ||
1103 | * needed. | ||
1104 | */ | ||
1105 | |||
1106 | static irqreturn_t ax_interrupt(int irq, void *dev_id) | ||
1107 | { | ||
1108 | struct net_device *dev = dev_id; | ||
1109 | long e8390_base; | ||
1110 | int interrupts, nr_serviced = 0, i; | ||
1111 | struct ei_device *ei_local; | ||
1112 | int handled = 0; | ||
1113 | unsigned long flags; | ||
1114 | |||
1115 | e8390_base = dev->base_addr; | ||
1116 | ei_local = netdev_priv(dev); | ||
1117 | |||
1118 | /* | ||
1119 | * Protect the irq test too. | ||
1120 | */ | ||
1121 | |||
1122 | spin_lock_irqsave(&ei_local->page_lock, flags); | ||
1123 | |||
1124 | if (ei_local->irqlock) { | ||
1125 | #if 1 /* This might just be an interrupt for a PCI device sharing this line */ | ||
1126 | const char *msg; | ||
1127 | /* The "irqlock" check is only for testing. */ | ||
1128 | if (ei_local->irqlock) | ||
1129 | msg = "Interrupted while interrupts are masked!"; | ||
1130 | else | ||
1131 | msg = "Reentering the interrupt handler!"; | ||
1132 | netdev_info(dev, "%s, isr=%#2x imr=%#2x\n", | ||
1133 | msg, | ||
1134 | inb_p(e8390_base + EN0_ISR), | ||
1135 | inb_p(e8390_base + EN0_IMR)); | ||
1136 | #endif | ||
1137 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
1138 | return IRQ_NONE; | ||
1139 | } | ||
1140 | |||
1141 | if (ei_debug > 3) | ||
1142 | netdev_printk(KERN_DEBUG, dev, "interrupt(isr=%#2.2x)\n", | ||
1143 | inb_p(e8390_base + EN0_ISR)); | ||
1144 | |||
1145 | outb_p(0x00, e8390_base + EN0_ISR); | ||
1146 | ei_local->irqlock = 1; | ||
1147 | |||
1148 | /* !!Assumption!! -- we stay in page 0. Don't break this. */ | ||
1149 | while ((interrupts = inb_p(e8390_base + EN0_ISR)) != 0 && | ||
1150 | ++nr_serviced < MAX_SERVICE) | ||
1151 | { | ||
1152 | if (!netif_running(dev) || (interrupts == 0xff)) { | ||
1153 | if (ei_debug > 1) | ||
1154 | netdev_warn(dev, | ||
1155 | "interrupt from stopped card\n"); | ||
1156 | outb_p(interrupts, e8390_base + EN0_ISR); | ||
1157 | interrupts = 0; | ||
1158 | break; | ||
1159 | } | ||
1160 | handled = 1; | ||
1161 | |||
1162 | /* AX88190 bug fix. */ | ||
1163 | outb_p(interrupts, e8390_base + EN0_ISR); | ||
1164 | for (i = 0; i < 10; i++) { | ||
1165 | if (!(inb(e8390_base + EN0_ISR) & interrupts)) | ||
1166 | break; | ||
1167 | outb_p(0, e8390_base + EN0_ISR); | ||
1168 | outb_p(interrupts, e8390_base + EN0_ISR); | ||
1169 | } | ||
1170 | if (interrupts & ENISR_OVER) | ||
1171 | ei_rx_overrun(dev); | ||
1172 | else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) | ||
1173 | { | ||
1174 | /* Got a good (?) packet. */ | ||
1175 | ei_receive(dev); | ||
1176 | } | ||
1177 | /* Push the next to-transmit packet through. */ | ||
1178 | if (interrupts & ENISR_TX) | ||
1179 | ei_tx_intr(dev); | ||
1180 | else if (interrupts & ENISR_TX_ERR) | ||
1181 | ei_tx_err(dev); | ||
1182 | |||
1183 | if (interrupts & ENISR_COUNTERS) | ||
1184 | { | ||
1185 | dev->stats.rx_frame_errors += inb_p(e8390_base + EN0_COUNTER0); | ||
1186 | dev->stats.rx_crc_errors += inb_p(e8390_base + EN0_COUNTER1); | ||
1187 | dev->stats.rx_missed_errors+= inb_p(e8390_base + EN0_COUNTER2); | ||
1188 | } | ||
1189 | } | ||
1190 | |||
1191 | if (interrupts && ei_debug > 3) | ||
1192 | { | ||
1193 | handled = 1; | ||
1194 | if (nr_serviced >= MAX_SERVICE) | ||
1195 | { | ||
1196 | /* 0xFF is valid for a card removal */ | ||
1197 | if(interrupts!=0xFF) | ||
1198 | netdev_warn(dev, "Too much work at interrupt, status %#2.2x\n", | ||
1199 | interrupts); | ||
1200 | outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */ | ||
1201 | } else { | ||
1202 | netdev_warn(dev, "unknown interrupt %#2x\n", | ||
1203 | interrupts); | ||
1204 | outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */ | ||
1205 | } | ||
1206 | } | ||
1207 | |||
1208 | /* Turn 8390 interrupts back on. */ | ||
1209 | ei_local->irqlock = 0; | ||
1210 | outb_p(ENISR_ALL, e8390_base + EN0_IMR); | ||
1211 | |||
1212 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
1213 | return IRQ_RETVAL(handled); | ||
1214 | } | ||
1215 | |||
1216 | /** | ||
1217 | * ei_tx_err - handle transmitter error | ||
1218 | * @dev: network device which threw the exception | ||
1219 | * | ||
1220 | * A transmitter error has happened. Most likely excess collisions (which | ||
1221 | * is a fairly normal condition). If the error is one where the Tx will | ||
1222 | * have been aborted, we try and send another one right away, instead of | ||
1223 | * letting the failed packet sit and collect dust in the Tx buffer. This | ||
1224 | * is a much better solution as it avoids kernel based Tx timeouts, and | ||
1225 | * an unnecessary card reset. | ||
1226 | * | ||
1227 | * Called with lock held. | ||
1228 | */ | ||
1229 | |||
1230 | static void ei_tx_err(struct net_device *dev) | ||
1231 | { | ||
1232 | long e8390_base = dev->base_addr; | ||
1233 | unsigned char txsr = inb_p(e8390_base+EN0_TSR); | ||
1234 | unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU); | ||
1235 | |||
1236 | #ifdef VERBOSE_ERROR_DUMP | ||
1237 | netdev_printk(KERN_DEBUG, dev, | ||
1238 | "transmitter error (%#2x):", txsr); | ||
1239 | if (txsr & ENTSR_ABT) | ||
1240 | pr_cont(" excess-collisions"); | ||
1241 | if (txsr & ENTSR_ND) | ||
1242 | pr_cont(" non-deferral"); | ||
1243 | if (txsr & ENTSR_CRS) | ||
1244 | pr_cont(" lost-carrier"); | ||
1245 | if (txsr & ENTSR_FU) | ||
1246 | pr_cont(" FIFO-underrun"); | ||
1247 | if (txsr & ENTSR_CDH) | ||
1248 | pr_cont(" lost-heartbeat"); | ||
1249 | pr_cont("\n"); | ||
1250 | #endif | ||
1251 | |||
1252 | if (tx_was_aborted) | ||
1253 | ei_tx_intr(dev); | ||
1254 | else | ||
1255 | { | ||
1256 | dev->stats.tx_errors++; | ||
1257 | if (txsr & ENTSR_CRS) dev->stats.tx_carrier_errors++; | ||
1258 | if (txsr & ENTSR_CDH) dev->stats.tx_heartbeat_errors++; | ||
1259 | if (txsr & ENTSR_OWC) dev->stats.tx_window_errors++; | ||
1260 | } | ||
1261 | } | ||
1262 | |||
1263 | /** | ||
1264 | * ei_tx_intr - transmit interrupt handler | ||
1265 | * @dev: network device for which tx intr is handled | ||
1266 | * | ||
1267 | * We have finished a transmit: check for errors and then trigger the next | ||
1268 | * packet to be sent. Called with lock held. | ||
1269 | */ | ||
1270 | |||
1271 | static void ei_tx_intr(struct net_device *dev) | ||
1272 | { | ||
1273 | long e8390_base = dev->base_addr; | ||
1274 | struct ei_device *ei_local = netdev_priv(dev); | ||
1275 | int status = inb(e8390_base + EN0_TSR); | ||
1276 | |||
1277 | /* | ||
1278 | * There are two Tx buffers, see which one finished, and trigger | ||
1279 | * the send of another one if it exists. | ||
1280 | */ | ||
1281 | ei_local->txqueue--; | ||
1282 | |||
1283 | if (ei_local->tx1 < 0) | ||
1284 | { | ||
1285 | if (ei_local->lasttx != 1 && ei_local->lasttx != -1) | ||
1286 | netdev_err(dev, "%s: bogus last_tx_buffer %d, tx1=%d\n", | ||
1287 | ei_local->name, ei_local->lasttx, | ||
1288 | ei_local->tx1); | ||
1289 | ei_local->tx1 = 0; | ||
1290 | if (ei_local->tx2 > 0) | ||
1291 | { | ||
1292 | ei_local->txing = 1; | ||
1293 | NS8390_trigger_send(dev, ei_local->tx2, ei_local->tx_start_page + 6); | ||
1294 | dev->trans_start = jiffies; | ||
1295 | ei_local->tx2 = -1, | ||
1296 | ei_local->lasttx = 2; | ||
1297 | } | ||
1298 | else ei_local->lasttx = 20, ei_local->txing = 0; | ||
1299 | } | ||
1300 | else if (ei_local->tx2 < 0) | ||
1301 | { | ||
1302 | if (ei_local->lasttx != 2 && ei_local->lasttx != -2) | ||
1303 | netdev_info(dev, "%s: bogus last_tx_buffer %d, tx2=%d\n", | ||
1304 | ei_local->name, ei_local->lasttx, | ||
1305 | ei_local->tx2); | ||
1306 | ei_local->tx2 = 0; | ||
1307 | if (ei_local->tx1 > 0) | ||
1308 | { | ||
1309 | ei_local->txing = 1; | ||
1310 | NS8390_trigger_send(dev, ei_local->tx1, ei_local->tx_start_page); | ||
1311 | dev->trans_start = jiffies; | ||
1312 | ei_local->tx1 = -1; | ||
1313 | ei_local->lasttx = 1; | ||
1314 | } | ||
1315 | else | ||
1316 | ei_local->lasttx = 10, ei_local->txing = 0; | ||
1317 | } | ||
1318 | // else | ||
1319 | // netdev_warn(dev, "unexpected TX-done interrupt, lasttx=%d\n", | ||
1320 | // ei_local->lasttx); | ||
1321 | |||
1322 | /* Minimize Tx latency: update the statistics after we restart TXing. */ | ||
1323 | if (status & ENTSR_COL) | ||
1324 | dev->stats.collisions++; | ||
1325 | if (status & ENTSR_PTX) | ||
1326 | dev->stats.tx_packets++; | ||
1327 | else | ||
1328 | { | ||
1329 | dev->stats.tx_errors++; | ||
1330 | if (status & ENTSR_ABT) | ||
1331 | { | ||
1332 | dev->stats.tx_aborted_errors++; | ||
1333 | dev->stats.collisions += 16; | ||
1334 | } | ||
1335 | if (status & ENTSR_CRS) | ||
1336 | dev->stats.tx_carrier_errors++; | ||
1337 | if (status & ENTSR_FU) | ||
1338 | dev->stats.tx_fifo_errors++; | ||
1339 | if (status & ENTSR_CDH) | ||
1340 | dev->stats.tx_heartbeat_errors++; | ||
1341 | if (status & ENTSR_OWC) | ||
1342 | dev->stats.tx_window_errors++; | ||
1343 | } | ||
1344 | netif_wake_queue(dev); | ||
1345 | } | ||
1346 | |||
1347 | /** | ||
1348 | * ei_receive - receive some packets | ||
1349 | * @dev: network device with which receive will be run | ||
1350 | * | ||
1351 | * We have a good packet(s), get it/them out of the buffers. | ||
1352 | * Called with lock held. | ||
1353 | */ | ||
1354 | |||
1355 | static void ei_receive(struct net_device *dev) | ||
1356 | { | ||
1357 | long e8390_base = dev->base_addr; | ||
1358 | struct ei_device *ei_local = netdev_priv(dev); | ||
1359 | unsigned char rxing_page, this_frame, next_frame; | ||
1360 | unsigned short current_offset; | ||
1361 | int rx_pkt_count = 0; | ||
1362 | struct e8390_pkt_hdr rx_frame; | ||
1363 | |||
1364 | while (++rx_pkt_count < 10) | ||
1365 | { | ||
1366 | int pkt_len, pkt_stat; | ||
1367 | |||
1368 | /* Get the rx page (incoming packet pointer). */ | ||
1369 | rxing_page = inb_p(e8390_base + EN1_CURPAG -1); | ||
1370 | |||
1371 | /* Remove one frame from the ring. Boundary is always a page behind. */ | ||
1372 | this_frame = inb_p(e8390_base + EN0_BOUNDARY) + 1; | ||
1373 | if (this_frame >= ei_local->stop_page) | ||
1374 | this_frame = ei_local->rx_start_page; | ||
1375 | |||
1376 | /* Someday we'll omit the previous, iff we never get this message. | ||
1377 | (There is at least one clone claimed to have a problem.) | ||
1378 | |||
1379 | Keep quiet if it looks like a card removal. One problem here | ||
1380 | is that some clones crash in roughly the same way. | ||
1381 | */ | ||
1382 | if (ei_debug > 0 && this_frame != ei_local->current_page && (this_frame!=0x0 || rxing_page!=0xFF)) | ||
1383 | netdev_err(dev, "mismatched read page pointers %2x vs %2x\n", | ||
1384 | this_frame, ei_local->current_page); | ||
1385 | |||
1386 | if (this_frame == rxing_page) /* Read all the frames? */ | ||
1387 | break; /* Done for now */ | ||
1388 | |||
1389 | current_offset = this_frame << 8; | ||
1390 | ei_get_8390_hdr(dev, &rx_frame, this_frame); | ||
1391 | |||
1392 | pkt_len = rx_frame.count - sizeof(struct e8390_pkt_hdr); | ||
1393 | pkt_stat = rx_frame.status; | ||
1394 | |||
1395 | next_frame = this_frame + 1 + ((pkt_len+4)>>8); | ||
1396 | |||
1397 | if (pkt_len < 60 || pkt_len > 1518) | ||
1398 | { | ||
1399 | if (ei_debug) | ||
1400 | netdev_printk(KERN_DEBUG, dev, | ||
1401 | "bogus packet size: %d, status=%#2x nxpg=%#2x\n", | ||
1402 | rx_frame.count, rx_frame.status, | ||
1403 | rx_frame.next); | ||
1404 | dev->stats.rx_errors++; | ||
1405 | dev->stats.rx_length_errors++; | ||
1406 | } | ||
1407 | else if ((pkt_stat & 0x0F) == ENRSR_RXOK) | ||
1408 | { | ||
1409 | struct sk_buff *skb; | ||
1410 | |||
1411 | skb = dev_alloc_skb(pkt_len+2); | ||
1412 | if (skb == NULL) | ||
1413 | { | ||
1414 | if (ei_debug > 1) | ||
1415 | netdev_printk(KERN_DEBUG, dev, | ||
1416 | "Couldn't allocate a sk_buff of size %d\n", | ||
1417 | pkt_len); | ||
1418 | dev->stats.rx_dropped++; | ||
1419 | break; | ||
1420 | } | ||
1421 | else | ||
1422 | { | ||
1423 | skb_reserve(skb,2); /* IP headers on 16 byte boundaries */ | ||
1424 | skb_put(skb, pkt_len); /* Make room */ | ||
1425 | ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame)); | ||
1426 | skb->protocol=eth_type_trans(skb,dev); | ||
1427 | netif_rx(skb); | ||
1428 | dev->stats.rx_packets++; | ||
1429 | dev->stats.rx_bytes += pkt_len; | ||
1430 | if (pkt_stat & ENRSR_PHY) | ||
1431 | dev->stats.multicast++; | ||
1432 | } | ||
1433 | } | ||
1434 | else | ||
1435 | { | ||
1436 | if (ei_debug) | ||
1437 | netdev_printk(KERN_DEBUG, dev, | ||
1438 | "bogus packet: status=%#2x nxpg=%#2x size=%d\n", | ||
1439 | rx_frame.status, rx_frame.next, | ||
1440 | rx_frame.count); | ||
1441 | dev->stats.rx_errors++; | ||
1442 | /* NB: The NIC counts CRC, frame and missed errors. */ | ||
1443 | if (pkt_stat & ENRSR_FO) | ||
1444 | dev->stats.rx_fifo_errors++; | ||
1445 | } | ||
1446 | next_frame = rx_frame.next; | ||
1447 | |||
1448 | /* This _should_ never happen: it's here for avoiding bad clones. */ | ||
1449 | if (next_frame >= ei_local->stop_page) { | ||
1450 | netdev_info(dev, "next frame inconsistency, %#2x\n", | ||
1451 | next_frame); | ||
1452 | next_frame = ei_local->rx_start_page; | ||
1453 | } | ||
1454 | ei_local->current_page = next_frame; | ||
1455 | outb_p(next_frame-1, e8390_base+EN0_BOUNDARY); | ||
1456 | } | ||
1457 | } | ||
1458 | |||
1459 | /** | ||
1460 | * ei_rx_overrun - handle receiver overrun | ||
1461 | * @dev: network device which threw exception | ||
1462 | * | ||
1463 | * We have a receiver overrun: we have to kick the 8390 to get it started | ||
1464 | * again. Problem is that you have to kick it exactly as NS prescribes in | ||
1465 | * the updated datasheets, or "the NIC may act in an unpredictable manner." | ||
1466 | * This includes causing "the NIC to defer indefinitely when it is stopped | ||
1467 | * on a busy network." Ugh. | ||
1468 | * Called with lock held. Don't call this with the interrupts off or your | ||
1469 | * computer will hate you - it takes 10ms or so. | ||
1470 | */ | ||
1471 | |||
1472 | static void ei_rx_overrun(struct net_device *dev) | ||
1473 | { | ||
1474 | axnet_dev_t *info = PRIV(dev); | ||
1475 | long e8390_base = dev->base_addr; | ||
1476 | unsigned char was_txing, must_resend = 0; | ||
1477 | |||
1478 | /* | ||
1479 | * Record whether a Tx was in progress and then issue the | ||
1480 | * stop command. | ||
1481 | */ | ||
1482 | was_txing = inb_p(e8390_base+E8390_CMD) & E8390_TRANS; | ||
1483 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); | ||
1484 | |||
1485 | if (ei_debug > 1) | ||
1486 | netdev_printk(KERN_DEBUG, dev, "Receiver overrun\n"); | ||
1487 | dev->stats.rx_over_errors++; | ||
1488 | |||
1489 | /* | ||
1490 | * Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total. | ||
1491 | * We wait at least 2ms. | ||
1492 | */ | ||
1493 | |||
1494 | mdelay(2); | ||
1495 | |||
1496 | /* | ||
1497 | * Reset RBCR[01] back to zero as per magic incantation. | ||
1498 | */ | ||
1499 | outb_p(0x00, e8390_base+EN0_RCNTLO); | ||
1500 | outb_p(0x00, e8390_base+EN0_RCNTHI); | ||
1501 | |||
1502 | /* | ||
1503 | * See if any Tx was interrupted or not. According to NS, this | ||
1504 | * step is vital, and skipping it will cause no end of havoc. | ||
1505 | */ | ||
1506 | |||
1507 | if (was_txing) | ||
1508 | { | ||
1509 | unsigned char tx_completed = inb_p(e8390_base+EN0_ISR) & (ENISR_TX+ENISR_TX_ERR); | ||
1510 | if (!tx_completed) | ||
1511 | must_resend = 1; | ||
1512 | } | ||
1513 | |||
1514 | /* | ||
1515 | * Have to enter loopback mode and then restart the NIC before | ||
1516 | * you are allowed to slurp packets up off the ring. | ||
1517 | */ | ||
1518 | outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); | ||
1519 | outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, e8390_base + E8390_CMD); | ||
1520 | |||
1521 | /* | ||
1522 | * Clear the Rx ring of all the debris, and ack the interrupt. | ||
1523 | */ | ||
1524 | ei_receive(dev); | ||
1525 | |||
1526 | /* | ||
1527 | * Leave loopback mode, and resend any packet that got stopped. | ||
1528 | */ | ||
1529 | outb_p(E8390_TXCONFIG | info->duplex_flag, e8390_base + EN0_TXCR); | ||
1530 | if (must_resend) | ||
1531 | outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, e8390_base + E8390_CMD); | ||
1532 | } | ||
1533 | |||
1534 | /* | ||
1535 | * Collect the stats. This is called unlocked and from several contexts. | ||
1536 | */ | ||
1537 | |||
1538 | static struct net_device_stats *get_stats(struct net_device *dev) | ||
1539 | { | ||
1540 | long ioaddr = dev->base_addr; | ||
1541 | struct ei_device *ei_local = netdev_priv(dev); | ||
1542 | unsigned long flags; | ||
1543 | |||
1544 | /* If the card is stopped, just return the present stats. */ | ||
1545 | if (!netif_running(dev)) | ||
1546 | return &dev->stats; | ||
1547 | |||
1548 | spin_lock_irqsave(&ei_local->page_lock,flags); | ||
1549 | /* Read the counter registers, assuming we are in page 0. */ | ||
1550 | dev->stats.rx_frame_errors += inb_p(ioaddr + EN0_COUNTER0); | ||
1551 | dev->stats.rx_crc_errors += inb_p(ioaddr + EN0_COUNTER1); | ||
1552 | dev->stats.rx_missed_errors+= inb_p(ioaddr + EN0_COUNTER2); | ||
1553 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
1554 | |||
1555 | return &dev->stats; | ||
1556 | } | ||
1557 | |||
1558 | /* | ||
1559 | * Form the 64 bit 8390 multicast table from the linked list of addresses | ||
1560 | * associated with this dev structure. | ||
1561 | */ | ||
1562 | |||
1563 | static inline void make_mc_bits(u8 *bits, struct net_device *dev) | ||
1564 | { | ||
1565 | struct netdev_hw_addr *ha; | ||
1566 | u32 crc; | ||
1567 | |||
1568 | netdev_for_each_mc_addr(ha, dev) { | ||
1569 | crc = ether_crc(ETH_ALEN, ha->addr); | ||
1570 | /* | ||
1571 | * The 8390 uses the 6 most significant bits of the | ||
1572 | * CRC to index the multicast table. | ||
1573 | */ | ||
1574 | bits[crc>>29] |= (1<<((crc>>26)&7)); | ||
1575 | } | ||
1576 | } | ||
1577 | |||
1578 | /** | ||
1579 | * do_set_multicast_list - set/clear multicast filter | ||
1580 | * @dev: net device for which multicast filter is adjusted | ||
1581 | * | ||
1582 | * Set or clear the multicast filter for this adaptor. | ||
1583 | * Must be called with lock held. | ||
1584 | */ | ||
1585 | |||
1586 | static void do_set_multicast_list(struct net_device *dev) | ||
1587 | { | ||
1588 | long e8390_base = dev->base_addr; | ||
1589 | int i; | ||
1590 | struct ei_device *ei_local = netdev_priv(dev); | ||
1591 | |||
1592 | if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) { | ||
1593 | memset(ei_local->mcfilter, 0, 8); | ||
1594 | if (!netdev_mc_empty(dev)) | ||
1595 | make_mc_bits(ei_local->mcfilter, dev); | ||
1596 | } else { | ||
1597 | /* set to accept-all */ | ||
1598 | memset(ei_local->mcfilter, 0xFF, 8); | ||
1599 | } | ||
1600 | |||
1601 | outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD); | ||
1602 | for(i = 0; i < 8; i++) | ||
1603 | { | ||
1604 | outb_p(ei_local->mcfilter[i], e8390_base + EN1_MULT_SHIFT(i)); | ||
1605 | } | ||
1606 | outb_p(E8390_NODMA + E8390_PAGE0, e8390_base + E8390_CMD); | ||
1607 | |||
1608 | if(dev->flags&IFF_PROMISC) | ||
1609 | outb_p(E8390_RXCONFIG | 0x58, e8390_base + EN0_RXCR); | ||
1610 | else if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev)) | ||
1611 | outb_p(E8390_RXCONFIG | 0x48, e8390_base + EN0_RXCR); | ||
1612 | else | ||
1613 | outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR); | ||
1614 | |||
1615 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD); | ||
1616 | } | ||
1617 | |||
1618 | /* | ||
1619 | * Called without lock held. This is invoked from user context and may | ||
1620 | * be parallel to just about everything else. Its also fairly quick and | ||
1621 | * not called too often. Must protect against both bh and irq users | ||
1622 | */ | ||
1623 | |||
1624 | static void set_multicast_list(struct net_device *dev) | ||
1625 | { | ||
1626 | unsigned long flags; | ||
1627 | |||
1628 | spin_lock_irqsave(&dev_lock(dev), flags); | ||
1629 | do_set_multicast_list(dev); | ||
1630 | spin_unlock_irqrestore(&dev_lock(dev), flags); | ||
1631 | } | ||
1632 | |||
1633 | /* This page of functions should be 8390 generic */ | ||
1634 | /* Follow National Semi's recommendations for initializing the "NIC". */ | ||
1635 | |||
1636 | /** | ||
1637 | * AX88190_init - initialize 8390 hardware | ||
1638 | * @dev: network device to initialize | ||
1639 | * @startp: boolean. non-zero value to initiate chip processing | ||
1640 | * | ||
1641 | * Must be called with lock held. | ||
1642 | */ | ||
1643 | |||
1644 | static void AX88190_init(struct net_device *dev, int startp) | ||
1645 | { | ||
1646 | axnet_dev_t *info = PRIV(dev); | ||
1647 | long e8390_base = dev->base_addr; | ||
1648 | struct ei_device *ei_local = netdev_priv(dev); | ||
1649 | int i; | ||
1650 | int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48; | ||
1651 | |||
1652 | if(sizeof(struct e8390_pkt_hdr)!=4) | ||
1653 | panic("8390.c: header struct mispacked\n"); | ||
1654 | /* Follow National Semi's recommendations for initing the DP83902. */ | ||
1655 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); /* 0x21 */ | ||
1656 | outb_p(endcfg, e8390_base + EN0_DCFG); /* 0x48 or 0x49 */ | ||
1657 | /* Clear the remote byte count registers. */ | ||
1658 | outb_p(0x00, e8390_base + EN0_RCNTLO); | ||
1659 | outb_p(0x00, e8390_base + EN0_RCNTHI); | ||
1660 | /* Set to monitor and loopback mode -- this is vital!. */ | ||
1661 | outb_p(E8390_RXOFF|0x40, e8390_base + EN0_RXCR); /* 0x60 */ | ||
1662 | outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); /* 0x02 */ | ||
1663 | /* Set the transmit page and receive ring. */ | ||
1664 | outb_p(ei_local->tx_start_page, e8390_base + EN0_TPSR); | ||
1665 | ei_local->tx1 = ei_local->tx2 = 0; | ||
1666 | outb_p(ei_local->rx_start_page, e8390_base + EN0_STARTPG); | ||
1667 | outb_p(ei_local->stop_page-1, e8390_base + EN0_BOUNDARY); /* 3c503 says 0x3f,NS0x26*/ | ||
1668 | ei_local->current_page = ei_local->rx_start_page; /* assert boundary+1 */ | ||
1669 | outb_p(ei_local->stop_page, e8390_base + EN0_STOPPG); | ||
1670 | /* Clear the pending interrupts and mask. */ | ||
1671 | outb_p(0xFF, e8390_base + EN0_ISR); | ||
1672 | outb_p(0x00, e8390_base + EN0_IMR); | ||
1673 | |||
1674 | /* Copy the station address into the DS8390 registers. */ | ||
1675 | |||
1676 | outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, e8390_base+E8390_CMD); /* 0x61 */ | ||
1677 | for(i = 0; i < 6; i++) | ||
1678 | { | ||
1679 | outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i)); | ||
1680 | if(inb_p(e8390_base + EN1_PHYS_SHIFT(i))!=dev->dev_addr[i]) | ||
1681 | netdev_err(dev, "Hw. address read/write mismap %d\n", i); | ||
1682 | } | ||
1683 | |||
1684 | outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); | ||
1685 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); | ||
1686 | |||
1687 | netif_start_queue(dev); | ||
1688 | ei_local->tx1 = ei_local->tx2 = 0; | ||
1689 | ei_local->txing = 0; | ||
1690 | |||
1691 | if (info->flags & IS_AX88790) /* select Internal PHY */ | ||
1692 | outb(0x10, e8390_base + AXNET_GPIO); | ||
1693 | |||
1694 | if (startp) | ||
1695 | { | ||
1696 | outb_p(0xff, e8390_base + EN0_ISR); | ||
1697 | outb_p(ENISR_ALL, e8390_base + EN0_IMR); | ||
1698 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD); | ||
1699 | outb_p(E8390_TXCONFIG | info->duplex_flag, | ||
1700 | e8390_base + EN0_TXCR); /* xmit on. */ | ||
1701 | /* 3c503 TechMan says rxconfig only after the NIC is started. */ | ||
1702 | outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR); /* rx on, */ | ||
1703 | do_set_multicast_list(dev); /* (re)load the mcast table */ | ||
1704 | } | ||
1705 | } | ||
1706 | |||
1707 | /* Trigger a transmit start, assuming the length is valid. | ||
1708 | Always called with the page lock held */ | ||
1709 | |||
1710 | static void NS8390_trigger_send(struct net_device *dev, unsigned int length, | ||
1711 | int start_page) | ||
1712 | { | ||
1713 | long e8390_base = dev->base_addr; | ||
1714 | struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev); | ||
1715 | |||
1716 | if (inb_p(e8390_base) & E8390_TRANS) | ||
1717 | { | ||
1718 | netdev_warn(dev, "trigger_send() called with the transmitter busy\n"); | ||
1719 | return; | ||
1720 | } | ||
1721 | outb_p(length & 0xff, e8390_base + EN0_TCNTLO); | ||
1722 | outb_p(length >> 8, e8390_base + EN0_TCNTHI); | ||
1723 | outb_p(start_page, e8390_base + EN0_TPSR); | ||
1724 | outb_p(E8390_NODMA+E8390_TRANS+E8390_START, e8390_base+E8390_CMD); | ||
1725 | } | ||
diff --git a/drivers/net/ethernet/8390/e2100.c b/drivers/net/ethernet/8390/e2100.c new file mode 100644 index 000000000000..d50a9998ae77 --- /dev/null +++ b/drivers/net/ethernet/8390/e2100.c | |||
@@ -0,0 +1,490 @@ | |||
1 | /* e2100.c: A Cabletron E2100 series ethernet driver for linux. */ | ||
2 | /* | ||
3 | Written 1993-1994 by Donald Becker. | ||
4 | |||
5 | Copyright 1994 by Donald Becker. | ||
6 | Copyright 1993 United States Government as represented by the | ||
7 | Director, National Security Agency. This software may be used and | ||
8 | distributed according to the terms of the GNU General Public License, | ||
9 | incorporated herein by reference. | ||
10 | |||
11 | This is a driver for the Cabletron E2100 series ethercards. | ||
12 | |||
13 | The Author may be reached as becker@scyld.com, or C/O | ||
14 | Scyld Computing Corporation | ||
15 | 410 Severn Ave., Suite 210 | ||
16 | Annapolis MD 21403 | ||
17 | |||
18 | The E2100 series ethercard is a fairly generic shared memory 8390 | ||
19 | implementation. The only unusual aspect is the way the shared memory | ||
20 | registers are set: first you do an inb() in what is normally the | ||
21 | station address region, and the low three bits of next outb() *address* | ||
22 | is used as the write value for that register. Either someone wasn't | ||
23 | too used to dem bit en bites, or they were trying to obfuscate the | ||
24 | programming interface. | ||
25 | |||
26 | There is an additional complication when setting the window on the packet | ||
27 | buffer. You must first do a read into the packet buffer region with the | ||
28 | low 8 address bits the address setting the page for the start of the packet | ||
29 | buffer window, and then do the above operation. See mem_on() for details. | ||
30 | |||
31 | One bug on the chip is that even a hard reset won't disable the memory | ||
32 | window, usually resulting in a hung machine if mem_off() isn't called. | ||
33 | If this happens, you must power down the machine for about 30 seconds. | ||
34 | */ | ||
35 | |||
36 | static const char version[] = | ||
37 | "e2100.c:v1.01 7/21/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; | ||
38 | |||
39 | #include <linux/module.h> | ||
40 | #include <linux/kernel.h> | ||
41 | #include <linux/errno.h> | ||
42 | #include <linux/string.h> | ||
43 | #include <linux/ioport.h> | ||
44 | #include <linux/netdevice.h> | ||
45 | #include <linux/etherdevice.h> | ||
46 | #include <linux/init.h> | ||
47 | #include <linux/interrupt.h> | ||
48 | #include <linux/delay.h> | ||
49 | |||
50 | #include <asm/io.h> | ||
51 | #include <asm/system.h> | ||
52 | |||
53 | #include "8390.h" | ||
54 | |||
55 | #define DRV_NAME "e2100" | ||
56 | |||
57 | static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0}; | ||
58 | |||
59 | /* Offsets from the base_addr. | ||
60 | Read from the ASIC register, and the low three bits of the next outb() | ||
61 | address is used to set the corresponding register. */ | ||
62 | #define E21_NIC_OFFSET 0 /* Offset to the 8390 NIC. */ | ||
63 | #define E21_ASIC 0x10 | ||
64 | #define E21_MEM_ENABLE 0x10 | ||
65 | #define E21_MEM_ON 0x05 /* Enable memory in 16 bit mode. */ | ||
66 | #define E21_MEM_ON_8 0x07 /* Enable memory in 8 bit mode. */ | ||
67 | #define E21_MEM_BASE 0x11 | ||
68 | #define E21_IRQ_LOW 0x12 /* The low three bits of the IRQ number. */ | ||
69 | #define E21_IRQ_HIGH 0x14 /* The high IRQ bit and media select ... */ | ||
70 | #define E21_MEDIA 0x14 /* (alias). */ | ||
71 | #define E21_ALT_IFPORT 0x02 /* Set to use the other (BNC,AUI) port. */ | ||
72 | #define E21_BIG_MEM 0x04 /* Use a bigger (64K) buffer (we don't) */ | ||
73 | #define E21_SAPROM 0x10 /* Offset to station address data. */ | ||
74 | #define E21_IO_EXTENT 0x20 | ||
75 | |||
76 | static inline void mem_on(short port, volatile char __iomem *mem_base, | ||
77 | unsigned char start_page ) | ||
78 | { | ||
79 | /* This is a little weird: set the shared memory window by doing a | ||
80 | read. The low address bits specify the starting page. */ | ||
81 | readb(mem_base+start_page); | ||
82 | inb(port + E21_MEM_ENABLE); | ||
83 | outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON); | ||
84 | } | ||
85 | |||
86 | static inline void mem_off(short port) | ||
87 | { | ||
88 | inb(port + E21_MEM_ENABLE); | ||
89 | outb(0x00, port + E21_MEM_ENABLE); | ||
90 | } | ||
91 | |||
92 | /* In other drivers I put the TX pages first, but the E2100 window circuitry | ||
93 | is designed to have a 4K Tx region last. The windowing circuitry wraps the | ||
94 | window at 0x2fff->0x0000 so that the packets at e.g. 0x2f00 in the RX ring | ||
95 | appear contiguously in the window. */ | ||
96 | #define E21_RX_START_PG 0x00 /* First page of RX buffer */ | ||
97 | #define E21_RX_STOP_PG 0x30 /* Last page +1 of RX ring */ | ||
98 | #define E21_BIG_RX_STOP_PG 0xF0 /* Last page +1 of RX ring */ | ||
99 | #define E21_TX_START_PG E21_RX_STOP_PG /* First page of TX buffer */ | ||
100 | |||
101 | static int e21_probe1(struct net_device *dev, int ioaddr); | ||
102 | |||
103 | static int e21_open(struct net_device *dev); | ||
104 | static void e21_reset_8390(struct net_device *dev); | ||
105 | static void e21_block_input(struct net_device *dev, int count, | ||
106 | struct sk_buff *skb, int ring_offset); | ||
107 | static void e21_block_output(struct net_device *dev, int count, | ||
108 | const unsigned char *buf, int start_page); | ||
109 | static void e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
110 | int ring_page); | ||
111 | static int e21_open(struct net_device *dev); | ||
112 | static int e21_close(struct net_device *dev); | ||
113 | |||
114 | |||
115 | /* Probe for the E2100 series ethercards. These cards have an 8390 at the | ||
116 | base address and the station address at both offset 0x10 and 0x18. I read | ||
117 | the station address from offset 0x18 to avoid the dataport of NE2000 | ||
118 | ethercards, and look for Ctron's unique ID (first three octets of the | ||
119 | station address). | ||
120 | */ | ||
121 | |||
122 | static int __init do_e2100_probe(struct net_device *dev) | ||
123 | { | ||
124 | int *port; | ||
125 | int base_addr = dev->base_addr; | ||
126 | int irq = dev->irq; | ||
127 | |||
128 | if (base_addr > 0x1ff) /* Check a single specified location. */ | ||
129 | return e21_probe1(dev, base_addr); | ||
130 | else if (base_addr != 0) /* Don't probe at all. */ | ||
131 | return -ENXIO; | ||
132 | |||
133 | for (port = e21_probe_list; *port; port++) { | ||
134 | dev->irq = irq; | ||
135 | if (e21_probe1(dev, *port) == 0) | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | return -ENODEV; | ||
140 | } | ||
141 | |||
142 | #ifndef MODULE | ||
143 | struct net_device * __init e2100_probe(int unit) | ||
144 | { | ||
145 | struct net_device *dev = alloc_ei_netdev(); | ||
146 | int err; | ||
147 | |||
148 | if (!dev) | ||
149 | return ERR_PTR(-ENOMEM); | ||
150 | |||
151 | sprintf(dev->name, "eth%d", unit); | ||
152 | netdev_boot_setup_check(dev); | ||
153 | |||
154 | err = do_e2100_probe(dev); | ||
155 | if (err) | ||
156 | goto out; | ||
157 | return dev; | ||
158 | out: | ||
159 | free_netdev(dev); | ||
160 | return ERR_PTR(err); | ||
161 | } | ||
162 | #endif | ||
163 | |||
164 | static const struct net_device_ops e21_netdev_ops = { | ||
165 | .ndo_open = e21_open, | ||
166 | .ndo_stop = e21_close, | ||
167 | |||
168 | .ndo_start_xmit = ei_start_xmit, | ||
169 | .ndo_tx_timeout = ei_tx_timeout, | ||
170 | .ndo_get_stats = ei_get_stats, | ||
171 | .ndo_set_multicast_list = ei_set_multicast_list, | ||
172 | .ndo_validate_addr = eth_validate_addr, | ||
173 | .ndo_set_mac_address = eth_mac_addr, | ||
174 | .ndo_change_mtu = eth_change_mtu, | ||
175 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
176 | .ndo_poll_controller = ei_poll, | ||
177 | #endif | ||
178 | }; | ||
179 | |||
180 | static int __init e21_probe1(struct net_device *dev, int ioaddr) | ||
181 | { | ||
182 | int i, status, retval; | ||
183 | unsigned char *station_addr = dev->dev_addr; | ||
184 | static unsigned version_printed; | ||
185 | |||
186 | if (!request_region(ioaddr, E21_IO_EXTENT, DRV_NAME)) | ||
187 | return -EBUSY; | ||
188 | |||
189 | /* First check the station address for the Ctron prefix. */ | ||
190 | if (inb(ioaddr + E21_SAPROM + 0) != 0x00 || | ||
191 | inb(ioaddr + E21_SAPROM + 1) != 0x00 || | ||
192 | inb(ioaddr + E21_SAPROM + 2) != 0x1d) { | ||
193 | retval = -ENODEV; | ||
194 | goto out; | ||
195 | } | ||
196 | |||
197 | /* Verify by making certain that there is a 8390 at there. */ | ||
198 | outb(E8390_NODMA + E8390_STOP, ioaddr); | ||
199 | udelay(1); /* we want to delay one I/O cycle - which is 2MHz */ | ||
200 | status = inb(ioaddr); | ||
201 | if (status != 0x21 && status != 0x23) { | ||
202 | retval = -ENODEV; | ||
203 | goto out; | ||
204 | } | ||
205 | |||
206 | /* Read the station address PROM. */ | ||
207 | for (i = 0; i < 6; i++) | ||
208 | station_addr[i] = inb(ioaddr + E21_SAPROM + i); | ||
209 | |||
210 | inb(ioaddr + E21_MEDIA); /* Point to media selection. */ | ||
211 | outb(0, ioaddr + E21_ASIC); /* and disable the secondary interface. */ | ||
212 | |||
213 | if (ei_debug && version_printed++ == 0) | ||
214 | printk(version); | ||
215 | |||
216 | for (i = 0; i < 6; i++) | ||
217 | printk(" %02X", station_addr[i]); | ||
218 | |||
219 | if (dev->irq < 2) { | ||
220 | static const int irqlist[] = {15, 11, 10, 12, 5, 9, 3, 4}; | ||
221 | for (i = 0; i < ARRAY_SIZE(irqlist); i++) | ||
222 | if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) { | ||
223 | dev->irq = irqlist[i]; | ||
224 | break; | ||
225 | } | ||
226 | if (i >= ARRAY_SIZE(irqlist)) { | ||
227 | printk(" unable to get IRQ %d.\n", dev->irq); | ||
228 | retval = -EAGAIN; | ||
229 | goto out; | ||
230 | } | ||
231 | } else if (dev->irq == 2) /* Fixup luser bogosity: IRQ2 is really IRQ9 */ | ||
232 | dev->irq = 9; | ||
233 | |||
234 | /* The 8390 is at the base address. */ | ||
235 | dev->base_addr = ioaddr; | ||
236 | |||
237 | ei_status.name = "E2100"; | ||
238 | ei_status.word16 = 1; | ||
239 | ei_status.tx_start_page = E21_TX_START_PG; | ||
240 | ei_status.rx_start_page = E21_RX_START_PG; | ||
241 | ei_status.stop_page = E21_RX_STOP_PG; | ||
242 | ei_status.saved_irq = dev->irq; | ||
243 | |||
244 | /* Check the media port used. The port can be passed in on the | ||
245 | low mem_end bits. */ | ||
246 | if (dev->mem_end & 15) | ||
247 | dev->if_port = dev->mem_end & 7; | ||
248 | else { | ||
249 | dev->if_port = 0; | ||
250 | inb(ioaddr + E21_MEDIA); /* Turn automatic media detection on. */ | ||
251 | for(i = 0; i < 6; i++) | ||
252 | if (station_addr[i] != inb(ioaddr + E21_SAPROM + 8 + i)) { | ||
253 | dev->if_port = 1; | ||
254 | break; | ||
255 | } | ||
256 | } | ||
257 | |||
258 | /* Never map in the E21 shared memory unless you are actively using it. | ||
259 | Also, the shared memory has effective only one setting -- spread all | ||
260 | over the 128K region! */ | ||
261 | if (dev->mem_start == 0) | ||
262 | dev->mem_start = 0xd0000; | ||
263 | |||
264 | ei_status.mem = ioremap(dev->mem_start, 2*1024); | ||
265 | if (!ei_status.mem) { | ||
266 | printk("unable to remap memory\n"); | ||
267 | retval = -EAGAIN; | ||
268 | goto out; | ||
269 | } | ||
270 | |||
271 | #ifdef notdef | ||
272 | /* These values are unused. The E2100 has a 2K window into the packet | ||
273 | buffer. The window can be set to start on any page boundary. */ | ||
274 | ei_status.rmem_start = dev->mem_start + TX_PAGES*256; | ||
275 | dev->mem_end = ei_status.rmem_end = dev->mem_start + 2*1024; | ||
276 | #endif | ||
277 | |||
278 | printk(", IRQ %d, %s media, memory @ %#lx.\n", dev->irq, | ||
279 | dev->if_port ? "secondary" : "primary", dev->mem_start); | ||
280 | |||
281 | ei_status.reset_8390 = &e21_reset_8390; | ||
282 | ei_status.block_input = &e21_block_input; | ||
283 | ei_status.block_output = &e21_block_output; | ||
284 | ei_status.get_8390_hdr = &e21_get_8390_hdr; | ||
285 | |||
286 | dev->netdev_ops = &e21_netdev_ops; | ||
287 | NS8390_init(dev, 0); | ||
288 | |||
289 | retval = register_netdev(dev); | ||
290 | if (retval) | ||
291 | goto out; | ||
292 | return 0; | ||
293 | out: | ||
294 | release_region(ioaddr, E21_IO_EXTENT); | ||
295 | return retval; | ||
296 | } | ||
297 | |||
298 | static int | ||
299 | e21_open(struct net_device *dev) | ||
300 | { | ||
301 | short ioaddr = dev->base_addr; | ||
302 | int retval; | ||
303 | |||
304 | if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) | ||
305 | return retval; | ||
306 | |||
307 | /* Set the interrupt line and memory base on the hardware. */ | ||
308 | inb(ioaddr + E21_IRQ_LOW); | ||
309 | outb(0, ioaddr + E21_ASIC + (dev->irq & 7)); | ||
310 | inb(ioaddr + E21_IRQ_HIGH); /* High IRQ bit, and if_port. */ | ||
311 | outb(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0) | ||
312 | + (dev->if_port ? E21_ALT_IFPORT : 0)); | ||
313 | inb(ioaddr + E21_MEM_BASE); | ||
314 | outb(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7)); | ||
315 | |||
316 | ei_open(dev); | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static void | ||
321 | e21_reset_8390(struct net_device *dev) | ||
322 | { | ||
323 | short ioaddr = dev->base_addr; | ||
324 | |||
325 | outb(0x01, ioaddr); | ||
326 | if (ei_debug > 1) printk("resetting the E2180x3 t=%ld...", jiffies); | ||
327 | ei_status.txing = 0; | ||
328 | |||
329 | /* Set up the ASIC registers, just in case something changed them. */ | ||
330 | |||
331 | if (ei_debug > 1) printk("reset done\n"); | ||
332 | } | ||
333 | |||
334 | /* Grab the 8390 specific header. We put the 2k window so the header page | ||
335 | appears at the start of the shared memory. */ | ||
336 | |||
337 | static void | ||
338 | e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
339 | { | ||
340 | |||
341 | short ioaddr = dev->base_addr; | ||
342 | char __iomem *shared_mem = ei_status.mem; | ||
343 | |||
344 | mem_on(ioaddr, shared_mem, ring_page); | ||
345 | |||
346 | #ifdef notdef | ||
347 | /* Officially this is what we are doing, but the readl() is faster */ | ||
348 | memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr)); | ||
349 | #else | ||
350 | ((unsigned int*)hdr)[0] = readl(shared_mem); | ||
351 | #endif | ||
352 | |||
353 | /* Turn off memory access: we would need to reprogram the window anyway. */ | ||
354 | mem_off(ioaddr); | ||
355 | |||
356 | } | ||
357 | |||
358 | /* Block input and output are easy on shared memory ethercards. | ||
359 | The E21xx makes block_input() especially easy by wrapping the top | ||
360 | ring buffer to the bottom automatically. */ | ||
361 | static void | ||
362 | e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
363 | { | ||
364 | short ioaddr = dev->base_addr; | ||
365 | char __iomem *shared_mem = ei_status.mem; | ||
366 | |||
367 | mem_on(ioaddr, shared_mem, (ring_offset>>8)); | ||
368 | |||
369 | memcpy_fromio(skb->data, ei_status.mem + (ring_offset & 0xff), count); | ||
370 | |||
371 | mem_off(ioaddr); | ||
372 | } | ||
373 | |||
374 | static void | ||
375 | e21_block_output(struct net_device *dev, int count, const unsigned char *buf, | ||
376 | int start_page) | ||
377 | { | ||
378 | short ioaddr = dev->base_addr; | ||
379 | volatile char __iomem *shared_mem = ei_status.mem; | ||
380 | |||
381 | /* Set the shared memory window start by doing a read, with the low address | ||
382 | bits specifying the starting page. */ | ||
383 | readb(shared_mem + start_page); | ||
384 | mem_on(ioaddr, shared_mem, start_page); | ||
385 | |||
386 | memcpy_toio(shared_mem, buf, count); | ||
387 | mem_off(ioaddr); | ||
388 | } | ||
389 | |||
390 | static int | ||
391 | e21_close(struct net_device *dev) | ||
392 | { | ||
393 | short ioaddr = dev->base_addr; | ||
394 | |||
395 | if (ei_debug > 1) | ||
396 | printk("%s: Shutting down ethercard.\n", dev->name); | ||
397 | |||
398 | free_irq(dev->irq, dev); | ||
399 | dev->irq = ei_status.saved_irq; | ||
400 | |||
401 | /* Shut off the interrupt line and secondary interface. */ | ||
402 | inb(ioaddr + E21_IRQ_LOW); | ||
403 | outb(0, ioaddr + E21_ASIC); | ||
404 | inb(ioaddr + E21_IRQ_HIGH); /* High IRQ bit, and if_port. */ | ||
405 | outb(0, ioaddr + E21_ASIC); | ||
406 | |||
407 | ei_close(dev); | ||
408 | |||
409 | /* Double-check that the memory has been turned off, because really | ||
410 | really bad things happen if it isn't. */ | ||
411 | mem_off(ioaddr); | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | |||
417 | #ifdef MODULE | ||
418 | #define MAX_E21_CARDS 4 /* Max number of E21 cards per module */ | ||
419 | static struct net_device *dev_e21[MAX_E21_CARDS]; | ||
420 | static int io[MAX_E21_CARDS]; | ||
421 | static int irq[MAX_E21_CARDS]; | ||
422 | static int mem[MAX_E21_CARDS]; | ||
423 | static int xcvr[MAX_E21_CARDS]; /* choose int. or ext. xcvr */ | ||
424 | |||
425 | module_param_array(io, int, NULL, 0); | ||
426 | module_param_array(irq, int, NULL, 0); | ||
427 | module_param_array(mem, int, NULL, 0); | ||
428 | module_param_array(xcvr, int, NULL, 0); | ||
429 | MODULE_PARM_DESC(io, "I/O base address(es)"); | ||
430 | MODULE_PARM_DESC(irq, "IRQ number(s)"); | ||
431 | MODULE_PARM_DESC(mem, " memory base address(es)"); | ||
432 | MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)"); | ||
433 | MODULE_DESCRIPTION("Cabletron E2100 ISA ethernet driver"); | ||
434 | MODULE_LICENSE("GPL"); | ||
435 | |||
436 | /* This is set up so that only a single autoprobe takes place per call. | ||
437 | ISA device autoprobes on a running machine are not recommended. */ | ||
438 | |||
439 | int __init init_module(void) | ||
440 | { | ||
441 | struct net_device *dev; | ||
442 | int this_dev, found = 0; | ||
443 | |||
444 | for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) { | ||
445 | if (io[this_dev] == 0) { | ||
446 | if (this_dev != 0) break; /* only autoprobe 1st one */ | ||
447 | printk(KERN_NOTICE "e2100.c: Presently autoprobing (not recommended) for a single card.\n"); | ||
448 | } | ||
449 | dev = alloc_ei_netdev(); | ||
450 | if (!dev) | ||
451 | break; | ||
452 | dev->irq = irq[this_dev]; | ||
453 | dev->base_addr = io[this_dev]; | ||
454 | dev->mem_start = mem[this_dev]; | ||
455 | dev->mem_end = xcvr[this_dev]; /* low 4bits = xcvr sel. */ | ||
456 | if (do_e2100_probe(dev) == 0) { | ||
457 | dev_e21[found++] = dev; | ||
458 | continue; | ||
459 | } | ||
460 | free_netdev(dev); | ||
461 | printk(KERN_WARNING "e2100.c: No E2100 card found (i/o = 0x%x).\n", io[this_dev]); | ||
462 | break; | ||
463 | } | ||
464 | if (found) | ||
465 | return 0; | ||
466 | return -ENXIO; | ||
467 | } | ||
468 | |||
469 | static void cleanup_card(struct net_device *dev) | ||
470 | { | ||
471 | /* NB: e21_close() handles free_irq */ | ||
472 | iounmap(ei_status.mem); | ||
473 | release_region(dev->base_addr, E21_IO_EXTENT); | ||
474 | } | ||
475 | |||
476 | void __exit | ||
477 | cleanup_module(void) | ||
478 | { | ||
479 | int this_dev; | ||
480 | |||
481 | for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) { | ||
482 | struct net_device *dev = dev_e21[this_dev]; | ||
483 | if (dev) { | ||
484 | unregister_netdev(dev); | ||
485 | cleanup_card(dev); | ||
486 | free_netdev(dev); | ||
487 | } | ||
488 | } | ||
489 | } | ||
490 | #endif /* MODULE */ | ||
diff --git a/drivers/net/ethernet/8390/es3210.c b/drivers/net/ethernet/8390/es3210.c new file mode 100644 index 000000000000..7a09575ecff0 --- /dev/null +++ b/drivers/net/ethernet/8390/es3210.c | |||
@@ -0,0 +1,446 @@ | |||
1 | /* | ||
2 | es3210.c | ||
3 | |||
4 | Linux driver for Racal-Interlan ES3210 EISA Network Adapter | ||
5 | |||
6 | Copyright (C) 1996, Paul Gortmaker. | ||
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 | Information and Code Sources: | ||
12 | |||
13 | 1) The existing myriad of Linux 8390 drivers written by Donald Becker. | ||
14 | |||
15 | 2) Once again Russ Nelson's asm packet driver provided additional info. | ||
16 | |||
17 | 3) Info for getting IRQ and sh-mem gleaned from the EISA cfg files. | ||
18 | Too bad it doesn't work -- see below. | ||
19 | |||
20 | The ES3210 is an EISA shared memory NS8390 implementation. Note | ||
21 | that all memory copies to/from the board must be 32bit transfers. | ||
22 | Which rules out using eth_io_copy_and_sum() in this driver. | ||
23 | |||
24 | Apparently there are two slightly different revisions of the | ||
25 | card, since there are two distinct EISA cfg files (!rii0101.cfg | ||
26 | and !rii0102.cfg) One has media select in the cfg file and the | ||
27 | other doesn't. Hopefully this will work with either. | ||
28 | |||
29 | That is about all I can tell you about it, having never actually | ||
30 | even seen one of these cards. :) Try http://www.interlan.com | ||
31 | if you want more info. | ||
32 | |||
33 | Thanks go to Mark Salazar for testing v0.02 of this driver. | ||
34 | |||
35 | Bugs, to-fix, etc: | ||
36 | |||
37 | 1) The EISA cfg ports that are *supposed* to have the IRQ and shared | ||
38 | mem values just read 0xff all the time. Hrrmpf. Apparently the | ||
39 | same happens with the packet driver as the code for reading | ||
40 | these registers is disabled there. In the meantime, boot with: | ||
41 | ether=<IRQ>,0,0x<shared_mem_addr>,eth0 to override the IRQ and | ||
42 | shared memory detection. (The i/o port detection is okay.) | ||
43 | |||
44 | 2) Module support currently untested. Probably works though. | ||
45 | |||
46 | */ | ||
47 | |||
48 | static const char version[] = | ||
49 | "es3210.c: Driver revision v0.03, 14/09/96\n"; | ||
50 | |||
51 | #include <linux/module.h> | ||
52 | #include <linux/eisa.h> | ||
53 | #include <linux/kernel.h> | ||
54 | #include <linux/errno.h> | ||
55 | #include <linux/string.h> | ||
56 | #include <linux/init.h> | ||
57 | #include <linux/interrupt.h> | ||
58 | #include <linux/netdevice.h> | ||
59 | #include <linux/etherdevice.h> | ||
60 | |||
61 | #include <asm/io.h> | ||
62 | #include <asm/system.h> | ||
63 | |||
64 | #include "8390.h" | ||
65 | |||
66 | static int es_probe1(struct net_device *dev, int ioaddr); | ||
67 | |||
68 | static void es_reset_8390(struct net_device *dev); | ||
69 | |||
70 | static void es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); | ||
71 | static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); | ||
72 | static void es_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page); | ||
73 | |||
74 | #define ES_START_PG 0x00 /* First page of TX buffer */ | ||
75 | #define ES_STOP_PG 0x40 /* Last page +1 of RX ring */ | ||
76 | |||
77 | #define ES_IO_EXTENT 0x37 /* The cfg file says 0xc90 -> 0xcc7 */ | ||
78 | #define ES_ID_PORT 0xc80 /* Same for all EISA cards */ | ||
79 | #define ES_SA_PROM 0xc90 /* Start of e'net addr. */ | ||
80 | #define ES_RESET_PORT 0xc84 /* From the packet driver source */ | ||
81 | #define ES_NIC_OFFSET 0xca0 /* Hello, the 8390 is *here* */ | ||
82 | |||
83 | #define ES_ADDR0 0x02 /* 3 byte vendor prefix */ | ||
84 | #define ES_ADDR1 0x07 | ||
85 | #define ES_ADDR2 0x01 | ||
86 | |||
87 | /* | ||
88 | * Two card revisions. EISA ID's are always rev. minor, rev. major,, and | ||
89 | * then the three vendor letters stored in 5 bits each, with an "a" = 1. | ||
90 | * For eg: "rii" = 10010 01001 01001 = 0x4929, which is how the EISA | ||
91 | * config utility determines automagically what config file(s) to use. | ||
92 | */ | ||
93 | #define ES_EISA_ID1 0x01012949 /* !rii0101.cfg */ | ||
94 | #define ES_EISA_ID2 0x02012949 /* !rii0102.cfg */ | ||
95 | |||
96 | #define ES_CFG1 0xcc0 /* IOPORT(1) --> IOPORT(6) in cfg file */ | ||
97 | #define ES_CFG2 0xcc1 | ||
98 | #define ES_CFG3 0xcc2 | ||
99 | #define ES_CFG4 0xcc3 | ||
100 | #define ES_CFG5 0xcc4 | ||
101 | #define ES_CFG6 0xc84 /* NB: 0xc84 is also "reset" port. */ | ||
102 | |||
103 | /* | ||
104 | * You can OR any of the following bits together and assign it | ||
105 | * to ES_DEBUG to get verbose driver info during operation. | ||
106 | * Some of these don't do anything yet. | ||
107 | */ | ||
108 | |||
109 | #define ES_D_PROBE 0x01 | ||
110 | #define ES_D_RX_PKT 0x02 | ||
111 | #define ES_D_TX_PKT 0x04 | ||
112 | #define ED_D_IRQ 0x08 | ||
113 | |||
114 | #define ES_DEBUG 0 | ||
115 | |||
116 | static unsigned char lo_irq_map[] __initdata = {3, 4, 5, 6, 7, 9, 10}; | ||
117 | static unsigned char hi_irq_map[] __initdata = {11, 12, 0, 14, 0, 0, 0, 15}; | ||
118 | |||
119 | /* | ||
120 | * Probe for the card. The best way is to read the EISA ID if it | ||
121 | * is known. Then we check the prefix of the station address | ||
122 | * PROM for a match against the Racal-Interlan assigned value. | ||
123 | */ | ||
124 | |||
125 | static int __init do_es_probe(struct net_device *dev) | ||
126 | { | ||
127 | unsigned short ioaddr = dev->base_addr; | ||
128 | int irq = dev->irq; | ||
129 | int mem_start = dev->mem_start; | ||
130 | |||
131 | if (ioaddr > 0x1ff) /* Check a single specified location. */ | ||
132 | return es_probe1(dev, ioaddr); | ||
133 | else if (ioaddr > 0) /* Don't probe at all. */ | ||
134 | return -ENXIO; | ||
135 | |||
136 | if (!EISA_bus) { | ||
137 | #if ES_DEBUG & ES_D_PROBE | ||
138 | printk("es3210.c: Not EISA bus. Not probing high ports.\n"); | ||
139 | #endif | ||
140 | return -ENXIO; | ||
141 | } | ||
142 | |||
143 | /* EISA spec allows for up to 16 slots, but 8 is typical. */ | ||
144 | for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { | ||
145 | if (es_probe1(dev, ioaddr) == 0) | ||
146 | return 0; | ||
147 | dev->irq = irq; | ||
148 | dev->mem_start = mem_start; | ||
149 | } | ||
150 | |||
151 | return -ENODEV; | ||
152 | } | ||
153 | |||
154 | #ifndef MODULE | ||
155 | struct net_device * __init es_probe(int unit) | ||
156 | { | ||
157 | struct net_device *dev = alloc_ei_netdev(); | ||
158 | int err; | ||
159 | |||
160 | if (!dev) | ||
161 | return ERR_PTR(-ENOMEM); | ||
162 | |||
163 | sprintf(dev->name, "eth%d", unit); | ||
164 | netdev_boot_setup_check(dev); | ||
165 | |||
166 | err = do_es_probe(dev); | ||
167 | if (err) | ||
168 | goto out; | ||
169 | return dev; | ||
170 | out: | ||
171 | free_netdev(dev); | ||
172 | return ERR_PTR(err); | ||
173 | } | ||
174 | #endif | ||
175 | |||
176 | static int __init es_probe1(struct net_device *dev, int ioaddr) | ||
177 | { | ||
178 | int i, retval; | ||
179 | unsigned long eisa_id; | ||
180 | |||
181 | if (!request_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT, "es3210")) | ||
182 | return -ENODEV; | ||
183 | |||
184 | #if ES_DEBUG & ES_D_PROBE | ||
185 | printk("es3210.c: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + ES_ID_PORT)); | ||
186 | printk("es3210.c: config regs: %#x %#x %#x %#x %#x %#x\n", | ||
187 | inb(ioaddr + ES_CFG1), inb(ioaddr + ES_CFG2), inb(ioaddr + ES_CFG3), | ||
188 | inb(ioaddr + ES_CFG4), inb(ioaddr + ES_CFG5), inb(ioaddr + ES_CFG6)); | ||
189 | #endif | ||
190 | |||
191 | /* Check the EISA ID of the card. */ | ||
192 | eisa_id = inl(ioaddr + ES_ID_PORT); | ||
193 | if ((eisa_id != ES_EISA_ID1) && (eisa_id != ES_EISA_ID2)) { | ||
194 | retval = -ENODEV; | ||
195 | goto out; | ||
196 | } | ||
197 | |||
198 | for (i = 0; i < ETHER_ADDR_LEN ; i++) | ||
199 | dev->dev_addr[i] = inb(ioaddr + ES_SA_PROM + i); | ||
200 | |||
201 | /* Check the Racal vendor ID as well. */ | ||
202 | if (dev->dev_addr[0] != ES_ADDR0 || | ||
203 | dev->dev_addr[1] != ES_ADDR1 || | ||
204 | dev->dev_addr[2] != ES_ADDR2) { | ||
205 | printk("es3210.c: card not found %pM (invalid_prefix).\n", | ||
206 | dev->dev_addr); | ||
207 | retval = -ENODEV; | ||
208 | goto out; | ||
209 | } | ||
210 | |||
211 | printk("es3210.c: ES3210 rev. %ld at %#x, node %pM", | ||
212 | eisa_id>>24, ioaddr, dev->dev_addr); | ||
213 | |||
214 | /* Snarf the interrupt now. */ | ||
215 | if (dev->irq == 0) { | ||
216 | unsigned char hi_irq = inb(ioaddr + ES_CFG2) & 0x07; | ||
217 | unsigned char lo_irq = inb(ioaddr + ES_CFG1) & 0xfe; | ||
218 | |||
219 | if (hi_irq != 0) { | ||
220 | dev->irq = hi_irq_map[hi_irq - 1]; | ||
221 | } else { | ||
222 | int i = 0; | ||
223 | while (lo_irq > (1<<i)) i++; | ||
224 | dev->irq = lo_irq_map[i]; | ||
225 | } | ||
226 | printk(" using IRQ %d", dev->irq); | ||
227 | #if ES_DEBUG & ES_D_PROBE | ||
228 | printk("es3210.c: hi_irq %#x, lo_irq %#x, dev->irq = %d\n", | ||
229 | hi_irq, lo_irq, dev->irq); | ||
230 | #endif | ||
231 | } else { | ||
232 | if (dev->irq == 2) | ||
233 | dev->irq = 9; /* Doh! */ | ||
234 | printk(" assigning IRQ %d", dev->irq); | ||
235 | } | ||
236 | |||
237 | if (request_irq(dev->irq, ei_interrupt, 0, "es3210", dev)) { | ||
238 | printk (" unable to get IRQ %d.\n", dev->irq); | ||
239 | retval = -EAGAIN; | ||
240 | goto out; | ||
241 | } | ||
242 | |||
243 | if (dev->mem_start == 0) { | ||
244 | unsigned char mem_enabled = inb(ioaddr + ES_CFG2) & 0xc0; | ||
245 | unsigned char mem_bits = inb(ioaddr + ES_CFG3) & 0x07; | ||
246 | |||
247 | if (mem_enabled != 0x80) { | ||
248 | printk(" shared mem disabled - giving up\n"); | ||
249 | retval = -ENXIO; | ||
250 | goto out1; | ||
251 | } | ||
252 | dev->mem_start = 0xC0000 + mem_bits*0x4000; | ||
253 | printk(" using "); | ||
254 | } else { | ||
255 | printk(" assigning "); | ||
256 | } | ||
257 | |||
258 | ei_status.mem = ioremap(dev->mem_start, (ES_STOP_PG - ES_START_PG)*256); | ||
259 | if (!ei_status.mem) { | ||
260 | printk("ioremap failed - giving up\n"); | ||
261 | retval = -ENXIO; | ||
262 | goto out1; | ||
263 | } | ||
264 | |||
265 | dev->mem_end = dev->mem_start + (ES_STOP_PG - ES_START_PG)*256; | ||
266 | |||
267 | printk("mem %#lx-%#lx\n", dev->mem_start, dev->mem_end-1); | ||
268 | |||
269 | #if ES_DEBUG & ES_D_PROBE | ||
270 | if (inb(ioaddr + ES_CFG5)) | ||
271 | printk("es3210: Warning - DMA channel enabled, but not used here.\n"); | ||
272 | #endif | ||
273 | /* Note, point at the 8390, and not the card... */ | ||
274 | dev->base_addr = ioaddr + ES_NIC_OFFSET; | ||
275 | |||
276 | ei_status.name = "ES3210"; | ||
277 | ei_status.tx_start_page = ES_START_PG; | ||
278 | ei_status.rx_start_page = ES_START_PG + TX_PAGES; | ||
279 | ei_status.stop_page = ES_STOP_PG; | ||
280 | ei_status.word16 = 1; | ||
281 | |||
282 | if (ei_debug > 0) | ||
283 | printk(version); | ||
284 | |||
285 | ei_status.reset_8390 = &es_reset_8390; | ||
286 | ei_status.block_input = &es_block_input; | ||
287 | ei_status.block_output = &es_block_output; | ||
288 | ei_status.get_8390_hdr = &es_get_8390_hdr; | ||
289 | |||
290 | dev->netdev_ops = &ei_netdev_ops; | ||
291 | NS8390_init(dev, 0); | ||
292 | |||
293 | retval = register_netdev(dev); | ||
294 | if (retval) | ||
295 | goto out1; | ||
296 | return 0; | ||
297 | out1: | ||
298 | free_irq(dev->irq, dev); | ||
299 | out: | ||
300 | release_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT); | ||
301 | return retval; | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * Reset as per the packet driver method. Judging by the EISA cfg | ||
306 | * file, this just toggles the "Board Enable" bits (bit 2 and 0). | ||
307 | */ | ||
308 | |||
309 | static void es_reset_8390(struct net_device *dev) | ||
310 | { | ||
311 | unsigned short ioaddr = dev->base_addr; | ||
312 | unsigned long end; | ||
313 | |||
314 | outb(0x04, ioaddr + ES_RESET_PORT); | ||
315 | if (ei_debug > 1) printk("%s: resetting the ES3210...", dev->name); | ||
316 | |||
317 | end = jiffies + 2*HZ/100; | ||
318 | while ((signed)(end - jiffies) > 0) continue; | ||
319 | |||
320 | ei_status.txing = 0; | ||
321 | outb(0x01, ioaddr + ES_RESET_PORT); | ||
322 | if (ei_debug > 1) printk("reset done\n"); | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * Note: In the following three functions is the implicit assumption | ||
327 | * that the associated memcpy will only use "rep; movsl" as long as | ||
328 | * we keep the counts as some multiple of doublewords. This is a | ||
329 | * requirement of the hardware, and also prevents us from using | ||
330 | * eth_io_copy_and_sum() since we can't guarantee it will limit | ||
331 | * itself to doubleword access. | ||
332 | */ | ||
333 | |||
334 | /* | ||
335 | * Grab the 8390 specific header. Similar to the block_input routine, but | ||
336 | * we don't need to be concerned with ring wrap as the header will be at | ||
337 | * the start of a page, so we optimize accordingly. (A single doubleword.) | ||
338 | */ | ||
339 | |||
340 | static void | ||
341 | es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
342 | { | ||
343 | void __iomem *hdr_start = ei_status.mem + ((ring_page - ES_START_PG)<<8); | ||
344 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
345 | hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */ | ||
346 | } | ||
347 | |||
348 | /* | ||
349 | * Block input and output are easy on shared memory ethercards, the only | ||
350 | * complication is when the ring buffer wraps. The count will already | ||
351 | * be rounded up to a doubleword value via es_get_8390_hdr() above. | ||
352 | */ | ||
353 | |||
354 | static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb, | ||
355 | int ring_offset) | ||
356 | { | ||
357 | void __iomem *xfer_start = ei_status.mem + ring_offset - ES_START_PG*256; | ||
358 | |||
359 | if (ring_offset + count > ES_STOP_PG*256) { | ||
360 | /* Packet wraps over end of ring buffer. */ | ||
361 | int semi_count = ES_STOP_PG*256 - ring_offset; | ||
362 | memcpy_fromio(skb->data, xfer_start, semi_count); | ||
363 | count -= semi_count; | ||
364 | memcpy_fromio(skb->data + semi_count, ei_status.mem, count); | ||
365 | } else { | ||
366 | /* Packet is in one chunk. */ | ||
367 | memcpy_fromio(skb->data, xfer_start, count); | ||
368 | } | ||
369 | } | ||
370 | |||
371 | static void es_block_output(struct net_device *dev, int count, | ||
372 | const unsigned char *buf, int start_page) | ||
373 | { | ||
374 | void __iomem *shmem = ei_status.mem + ((start_page - ES_START_PG)<<8); | ||
375 | |||
376 | count = (count + 3) & ~3; /* Round up to doubleword */ | ||
377 | memcpy_toio(shmem, buf, count); | ||
378 | } | ||
379 | |||
380 | #ifdef MODULE | ||
381 | #define MAX_ES_CARDS 4 /* Max number of ES3210 cards per module */ | ||
382 | #define NAMELEN 8 /* # of chars for storing dev->name */ | ||
383 | static struct net_device *dev_es3210[MAX_ES_CARDS]; | ||
384 | static int io[MAX_ES_CARDS]; | ||
385 | static int irq[MAX_ES_CARDS]; | ||
386 | static int mem[MAX_ES_CARDS]; | ||
387 | |||
388 | module_param_array(io, int, NULL, 0); | ||
389 | module_param_array(irq, int, NULL, 0); | ||
390 | module_param_array(mem, int, NULL, 0); | ||
391 | MODULE_PARM_DESC(io, "I/O base address(es)"); | ||
392 | MODULE_PARM_DESC(irq, "IRQ number(s)"); | ||
393 | MODULE_PARM_DESC(mem, "memory base address(es)"); | ||
394 | MODULE_DESCRIPTION("Racal-Interlan ES3210 EISA ethernet driver"); | ||
395 | MODULE_LICENSE("GPL"); | ||
396 | |||
397 | int __init init_module(void) | ||
398 | { | ||
399 | struct net_device *dev; | ||
400 | int this_dev, found = 0; | ||
401 | |||
402 | for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) { | ||
403 | if (io[this_dev] == 0 && this_dev != 0) | ||
404 | break; | ||
405 | dev = alloc_ei_netdev(); | ||
406 | if (!dev) | ||
407 | break; | ||
408 | dev->irq = irq[this_dev]; | ||
409 | dev->base_addr = io[this_dev]; | ||
410 | dev->mem_start = mem[this_dev]; | ||
411 | if (do_es_probe(dev) == 0) { | ||
412 | dev_es3210[found++] = dev; | ||
413 | continue; | ||
414 | } | ||
415 | free_netdev(dev); | ||
416 | printk(KERN_WARNING "es3210.c: No es3210 card found (i/o = 0x%x).\n", io[this_dev]); | ||
417 | break; | ||
418 | } | ||
419 | if (found) | ||
420 | return 0; | ||
421 | return -ENXIO; | ||
422 | } | ||
423 | |||
424 | static void cleanup_card(struct net_device *dev) | ||
425 | { | ||
426 | free_irq(dev->irq, dev); | ||
427 | release_region(dev->base_addr, ES_IO_EXTENT); | ||
428 | iounmap(ei_status.mem); | ||
429 | } | ||
430 | |||
431 | void __exit | ||
432 | cleanup_module(void) | ||
433 | { | ||
434 | int this_dev; | ||
435 | |||
436 | for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) { | ||
437 | struct net_device *dev = dev_es3210[this_dev]; | ||
438 | if (dev) { | ||
439 | unregister_netdev(dev); | ||
440 | cleanup_card(dev); | ||
441 | free_netdev(dev); | ||
442 | } | ||
443 | } | ||
444 | } | ||
445 | #endif /* MODULE */ | ||
446 | |||
diff --git a/drivers/net/ethernet/8390/etherh.c b/drivers/net/ethernet/8390/etherh.c new file mode 100644 index 000000000000..cf851faef311 --- /dev/null +++ b/drivers/net/ethernet/8390/etherh.c | |||
@@ -0,0 +1,866 @@ | |||
1 | /* | ||
2 | * linux/drivers/acorn/net/etherh.c | ||
3 | * | ||
4 | * Copyright (C) 2000-2002 Russell King | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * NS8390 I-cubed EtherH and ANT EtherM specific driver | ||
11 | * Thanks to I-Cubed for information on their cards. | ||
12 | * EtherM conversion (C) 1999 Chris Kemp and Tim Watterton | ||
13 | * EtherM integration (C) 2000 Aleph One Ltd (Tak-Shing Chan) | ||
14 | * EtherM integration re-engineered by Russell King. | ||
15 | * | ||
16 | * Changelog: | ||
17 | * 08-12-1996 RMK 1.00 Created | ||
18 | * RMK 1.03 Added support for EtherLan500 cards | ||
19 | * 23-11-1997 RMK 1.04 Added media autodetection | ||
20 | * 16-04-1998 RMK 1.05 Improved media autodetection | ||
21 | * 10-02-2000 RMK 1.06 Updated for 2.3.43 | ||
22 | * 13-05-2000 RMK 1.07 Updated for 2.3.99-pre8 | ||
23 | * 12-10-1999 CK/TEW EtherM driver first release | ||
24 | * 21-12-2000 TTC EtherH/EtherM integration | ||
25 | * 25-12-2000 RMK 1.08 Clean integration of EtherM into this driver. | ||
26 | * 03-01-2002 RMK 1.09 Always enable IRQs if we're in the nic slot. | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/types.h> | ||
32 | #include <linux/fcntl.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <linux/ioport.h> | ||
35 | #include <linux/in.h> | ||
36 | #include <linux/string.h> | ||
37 | #include <linux/errno.h> | ||
38 | #include <linux/netdevice.h> | ||
39 | #include <linux/etherdevice.h> | ||
40 | #include <linux/ethtool.h> | ||
41 | #include <linux/skbuff.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/device.h> | ||
44 | #include <linux/init.h> | ||
45 | #include <linux/bitops.h> | ||
46 | #include <linux/jiffies.h> | ||
47 | |||
48 | #include <asm/system.h> | ||
49 | #include <asm/ecard.h> | ||
50 | #include <asm/io.h> | ||
51 | |||
52 | #define EI_SHIFT(x) (ei_local->reg_offset[x]) | ||
53 | |||
54 | #define ei_inb(_p) readb((void __iomem *)_p) | ||
55 | #define ei_outb(_v,_p) writeb(_v,(void __iomem *)_p) | ||
56 | #define ei_inb_p(_p) readb((void __iomem *)_p) | ||
57 | #define ei_outb_p(_v,_p) writeb(_v,(void __iomem *)_p) | ||
58 | |||
59 | #define NET_DEBUG 0 | ||
60 | #define DEBUG_INIT 2 | ||
61 | |||
62 | #define DRV_NAME "etherh" | ||
63 | #define DRV_VERSION "1.11" | ||
64 | |||
65 | static char version[] __initdata = | ||
66 | "EtherH/EtherM Driver (c) 2002-2004 Russell King " DRV_VERSION "\n"; | ||
67 | |||
68 | #include "lib8390.c" | ||
69 | |||
70 | static unsigned int net_debug = NET_DEBUG; | ||
71 | |||
72 | struct etherh_priv { | ||
73 | void __iomem *ioc_fast; | ||
74 | void __iomem *memc; | ||
75 | void __iomem *dma_base; | ||
76 | unsigned int id; | ||
77 | void __iomem *ctrl_port; | ||
78 | unsigned char ctrl; | ||
79 | u32 supported; | ||
80 | }; | ||
81 | |||
82 | struct etherh_data { | ||
83 | unsigned long ns8390_offset; | ||
84 | unsigned long dataport_offset; | ||
85 | unsigned long ctrlport_offset; | ||
86 | int ctrl_ioc; | ||
87 | const char name[16]; | ||
88 | u32 supported; | ||
89 | unsigned char tx_start_page; | ||
90 | unsigned char stop_page; | ||
91 | }; | ||
92 | |||
93 | MODULE_AUTHOR("Russell King"); | ||
94 | MODULE_DESCRIPTION("EtherH/EtherM driver"); | ||
95 | MODULE_LICENSE("GPL"); | ||
96 | |||
97 | #define ETHERH500_DATAPORT 0x800 /* MEMC */ | ||
98 | #define ETHERH500_NS8390 0x000 /* MEMC */ | ||
99 | #define ETHERH500_CTRLPORT 0x800 /* IOC */ | ||
100 | |||
101 | #define ETHERH600_DATAPORT 0x040 /* MEMC */ | ||
102 | #define ETHERH600_NS8390 0x800 /* MEMC */ | ||
103 | #define ETHERH600_CTRLPORT 0x200 /* MEMC */ | ||
104 | |||
105 | #define ETHERH_CP_IE 1 | ||
106 | #define ETHERH_CP_IF 2 | ||
107 | #define ETHERH_CP_HEARTBEAT 2 | ||
108 | |||
109 | #define ETHERH_TX_START_PAGE 1 | ||
110 | #define ETHERH_STOP_PAGE 127 | ||
111 | |||
112 | /* | ||
113 | * These came from CK/TEW | ||
114 | */ | ||
115 | #define ETHERM_DATAPORT 0x200 /* MEMC */ | ||
116 | #define ETHERM_NS8390 0x800 /* MEMC */ | ||
117 | #define ETHERM_CTRLPORT 0x23c /* MEMC */ | ||
118 | |||
119 | #define ETHERM_TX_START_PAGE 64 | ||
120 | #define ETHERM_STOP_PAGE 127 | ||
121 | |||
122 | /* ------------------------------------------------------------------------ */ | ||
123 | |||
124 | #define etherh_priv(dev) \ | ||
125 | ((struct etherh_priv *)(((char *)netdev_priv(dev)) + sizeof(struct ei_device))) | ||
126 | |||
127 | static inline void etherh_set_ctrl(struct etherh_priv *eh, unsigned char mask) | ||
128 | { | ||
129 | unsigned char ctrl = eh->ctrl | mask; | ||
130 | eh->ctrl = ctrl; | ||
131 | writeb(ctrl, eh->ctrl_port); | ||
132 | } | ||
133 | |||
134 | static inline void etherh_clr_ctrl(struct etherh_priv *eh, unsigned char mask) | ||
135 | { | ||
136 | unsigned char ctrl = eh->ctrl & ~mask; | ||
137 | eh->ctrl = ctrl; | ||
138 | writeb(ctrl, eh->ctrl_port); | ||
139 | } | ||
140 | |||
141 | static inline unsigned int etherh_get_stat(struct etherh_priv *eh) | ||
142 | { | ||
143 | return readb(eh->ctrl_port); | ||
144 | } | ||
145 | |||
146 | |||
147 | |||
148 | |||
149 | static void etherh_irq_enable(ecard_t *ec, int irqnr) | ||
150 | { | ||
151 | struct etherh_priv *eh = ec->irq_data; | ||
152 | |||
153 | etherh_set_ctrl(eh, ETHERH_CP_IE); | ||
154 | } | ||
155 | |||
156 | static void etherh_irq_disable(ecard_t *ec, int irqnr) | ||
157 | { | ||
158 | struct etherh_priv *eh = ec->irq_data; | ||
159 | |||
160 | etherh_clr_ctrl(eh, ETHERH_CP_IE); | ||
161 | } | ||
162 | |||
163 | static expansioncard_ops_t etherh_ops = { | ||
164 | .irqenable = etherh_irq_enable, | ||
165 | .irqdisable = etherh_irq_disable, | ||
166 | }; | ||
167 | |||
168 | |||
169 | |||
170 | |||
171 | static void | ||
172 | etherh_setif(struct net_device *dev) | ||
173 | { | ||
174 | struct ei_device *ei_local = netdev_priv(dev); | ||
175 | unsigned long flags; | ||
176 | void __iomem *addr; | ||
177 | |||
178 | local_irq_save(flags); | ||
179 | |||
180 | /* set the interface type */ | ||
181 | switch (etherh_priv(dev)->id) { | ||
182 | case PROD_I3_ETHERLAN600: | ||
183 | case PROD_I3_ETHERLAN600A: | ||
184 | addr = (void __iomem *)dev->base_addr + EN0_RCNTHI; | ||
185 | |||
186 | switch (dev->if_port) { | ||
187 | case IF_PORT_10BASE2: | ||
188 | writeb((readb(addr) & 0xf8) | 1, addr); | ||
189 | break; | ||
190 | case IF_PORT_10BASET: | ||
191 | writeb((readb(addr) & 0xf8), addr); | ||
192 | break; | ||
193 | } | ||
194 | break; | ||
195 | |||
196 | case PROD_I3_ETHERLAN500: | ||
197 | switch (dev->if_port) { | ||
198 | case IF_PORT_10BASE2: | ||
199 | etherh_clr_ctrl(etherh_priv(dev), ETHERH_CP_IF); | ||
200 | break; | ||
201 | |||
202 | case IF_PORT_10BASET: | ||
203 | etherh_set_ctrl(etherh_priv(dev), ETHERH_CP_IF); | ||
204 | break; | ||
205 | } | ||
206 | break; | ||
207 | |||
208 | default: | ||
209 | break; | ||
210 | } | ||
211 | |||
212 | local_irq_restore(flags); | ||
213 | } | ||
214 | |||
215 | static int | ||
216 | etherh_getifstat(struct net_device *dev) | ||
217 | { | ||
218 | struct ei_device *ei_local = netdev_priv(dev); | ||
219 | void __iomem *addr; | ||
220 | int stat = 0; | ||
221 | |||
222 | switch (etherh_priv(dev)->id) { | ||
223 | case PROD_I3_ETHERLAN600: | ||
224 | case PROD_I3_ETHERLAN600A: | ||
225 | addr = (void __iomem *)dev->base_addr + EN0_RCNTHI; | ||
226 | switch (dev->if_port) { | ||
227 | case IF_PORT_10BASE2: | ||
228 | stat = 1; | ||
229 | break; | ||
230 | case IF_PORT_10BASET: | ||
231 | stat = readb(addr) & 4; | ||
232 | break; | ||
233 | } | ||
234 | break; | ||
235 | |||
236 | case PROD_I3_ETHERLAN500: | ||
237 | switch (dev->if_port) { | ||
238 | case IF_PORT_10BASE2: | ||
239 | stat = 1; | ||
240 | break; | ||
241 | case IF_PORT_10BASET: | ||
242 | stat = etherh_get_stat(etherh_priv(dev)) & ETHERH_CP_HEARTBEAT; | ||
243 | break; | ||
244 | } | ||
245 | break; | ||
246 | |||
247 | default: | ||
248 | stat = 0; | ||
249 | break; | ||
250 | } | ||
251 | |||
252 | return stat != 0; | ||
253 | } | ||
254 | |||
255 | /* | ||
256 | * Configure the interface. Note that we ignore the other | ||
257 | * parts of ifmap, since its mostly meaningless for this driver. | ||
258 | */ | ||
259 | static int etherh_set_config(struct net_device *dev, struct ifmap *map) | ||
260 | { | ||
261 | switch (map->port) { | ||
262 | case IF_PORT_10BASE2: | ||
263 | case IF_PORT_10BASET: | ||
264 | /* | ||
265 | * If the user explicitly sets the interface | ||
266 | * media type, turn off automedia detection. | ||
267 | */ | ||
268 | dev->flags &= ~IFF_AUTOMEDIA; | ||
269 | dev->if_port = map->port; | ||
270 | break; | ||
271 | |||
272 | default: | ||
273 | return -EINVAL; | ||
274 | } | ||
275 | |||
276 | etherh_setif(dev); | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | /* | ||
282 | * Reset the 8390 (hard reset). Note that we can't actually do this. | ||
283 | */ | ||
284 | static void | ||
285 | etherh_reset(struct net_device *dev) | ||
286 | { | ||
287 | struct ei_device *ei_local = netdev_priv(dev); | ||
288 | void __iomem *addr = (void __iomem *)dev->base_addr; | ||
289 | |||
290 | writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, addr); | ||
291 | |||
292 | /* | ||
293 | * See if we need to change the interface type. | ||
294 | * Note that we use 'interface_num' as a flag | ||
295 | * to indicate that we need to change the media. | ||
296 | */ | ||
297 | if (dev->flags & IFF_AUTOMEDIA && ei_local->interface_num) { | ||
298 | ei_local->interface_num = 0; | ||
299 | |||
300 | if (dev->if_port == IF_PORT_10BASET) | ||
301 | dev->if_port = IF_PORT_10BASE2; | ||
302 | else | ||
303 | dev->if_port = IF_PORT_10BASET; | ||
304 | |||
305 | etherh_setif(dev); | ||
306 | } | ||
307 | } | ||
308 | |||
309 | /* | ||
310 | * Write a block of data out to the 8390 | ||
311 | */ | ||
312 | static void | ||
313 | etherh_block_output (struct net_device *dev, int count, const unsigned char *buf, int start_page) | ||
314 | { | ||
315 | struct ei_device *ei_local = netdev_priv(dev); | ||
316 | unsigned long dma_start; | ||
317 | void __iomem *dma_base, *addr; | ||
318 | |||
319 | if (ei_local->dmaing) { | ||
320 | printk(KERN_ERR "%s: DMAing conflict in etherh_block_input: " | ||
321 | " DMAstat %d irqlock %d\n", dev->name, | ||
322 | ei_local->dmaing, ei_local->irqlock); | ||
323 | return; | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * Make sure we have a round number of bytes if we're in word mode. | ||
328 | */ | ||
329 | if (count & 1 && ei_local->word16) | ||
330 | count++; | ||
331 | |||
332 | ei_local->dmaing = 1; | ||
333 | |||
334 | addr = (void __iomem *)dev->base_addr; | ||
335 | dma_base = etherh_priv(dev)->dma_base; | ||
336 | |||
337 | count = (count + 1) & ~1; | ||
338 | writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); | ||
339 | |||
340 | writeb (0x42, addr + EN0_RCNTLO); | ||
341 | writeb (0x00, addr + EN0_RCNTHI); | ||
342 | writeb (0x42, addr + EN0_RSARLO); | ||
343 | writeb (0x00, addr + EN0_RSARHI); | ||
344 | writeb (E8390_RREAD | E8390_START, addr + E8390_CMD); | ||
345 | |||
346 | udelay (1); | ||
347 | |||
348 | writeb (ENISR_RDC, addr + EN0_ISR); | ||
349 | writeb (count, addr + EN0_RCNTLO); | ||
350 | writeb (count >> 8, addr + EN0_RCNTHI); | ||
351 | writeb (0, addr + EN0_RSARLO); | ||
352 | writeb (start_page, addr + EN0_RSARHI); | ||
353 | writeb (E8390_RWRITE | E8390_START, addr + E8390_CMD); | ||
354 | |||
355 | if (ei_local->word16) | ||
356 | writesw (dma_base, buf, count >> 1); | ||
357 | else | ||
358 | writesb (dma_base, buf, count); | ||
359 | |||
360 | dma_start = jiffies; | ||
361 | |||
362 | while ((readb (addr + EN0_ISR) & ENISR_RDC) == 0) | ||
363 | if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ | ||
364 | printk(KERN_ERR "%s: timeout waiting for TX RDC\n", | ||
365 | dev->name); | ||
366 | etherh_reset (dev); | ||
367 | __NS8390_init (dev, 1); | ||
368 | break; | ||
369 | } | ||
370 | |||
371 | writeb (ENISR_RDC, addr + EN0_ISR); | ||
372 | ei_local->dmaing = 0; | ||
373 | } | ||
374 | |||
375 | /* | ||
376 | * Read a block of data from the 8390 | ||
377 | */ | ||
378 | static void | ||
379 | etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
380 | { | ||
381 | struct ei_device *ei_local = netdev_priv(dev); | ||
382 | unsigned char *buf; | ||
383 | void __iomem *dma_base, *addr; | ||
384 | |||
385 | if (ei_local->dmaing) { | ||
386 | printk(KERN_ERR "%s: DMAing conflict in etherh_block_input: " | ||
387 | " DMAstat %d irqlock %d\n", dev->name, | ||
388 | ei_local->dmaing, ei_local->irqlock); | ||
389 | return; | ||
390 | } | ||
391 | |||
392 | ei_local->dmaing = 1; | ||
393 | |||
394 | addr = (void __iomem *)dev->base_addr; | ||
395 | dma_base = etherh_priv(dev)->dma_base; | ||
396 | |||
397 | buf = skb->data; | ||
398 | writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); | ||
399 | writeb (count, addr + EN0_RCNTLO); | ||
400 | writeb (count >> 8, addr + EN0_RCNTHI); | ||
401 | writeb (ring_offset, addr + EN0_RSARLO); | ||
402 | writeb (ring_offset >> 8, addr + EN0_RSARHI); | ||
403 | writeb (E8390_RREAD | E8390_START, addr + E8390_CMD); | ||
404 | |||
405 | if (ei_local->word16) { | ||
406 | readsw (dma_base, buf, count >> 1); | ||
407 | if (count & 1) | ||
408 | buf[count - 1] = readb (dma_base); | ||
409 | } else | ||
410 | readsb (dma_base, buf, count); | ||
411 | |||
412 | writeb (ENISR_RDC, addr + EN0_ISR); | ||
413 | ei_local->dmaing = 0; | ||
414 | } | ||
415 | |||
416 | /* | ||
417 | * Read a header from the 8390 | ||
418 | */ | ||
419 | static void | ||
420 | etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
421 | { | ||
422 | struct ei_device *ei_local = netdev_priv(dev); | ||
423 | void __iomem *dma_base, *addr; | ||
424 | |||
425 | if (ei_local->dmaing) { | ||
426 | printk(KERN_ERR "%s: DMAing conflict in etherh_get_header: " | ||
427 | " DMAstat %d irqlock %d\n", dev->name, | ||
428 | ei_local->dmaing, ei_local->irqlock); | ||
429 | return; | ||
430 | } | ||
431 | |||
432 | ei_local->dmaing = 1; | ||
433 | |||
434 | addr = (void __iomem *)dev->base_addr; | ||
435 | dma_base = etherh_priv(dev)->dma_base; | ||
436 | |||
437 | writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); | ||
438 | writeb (sizeof (*hdr), addr + EN0_RCNTLO); | ||
439 | writeb (0, addr + EN0_RCNTHI); | ||
440 | writeb (0, addr + EN0_RSARLO); | ||
441 | writeb (ring_page, addr + EN0_RSARHI); | ||
442 | writeb (E8390_RREAD | E8390_START, addr + E8390_CMD); | ||
443 | |||
444 | if (ei_local->word16) | ||
445 | readsw (dma_base, hdr, sizeof (*hdr) >> 1); | ||
446 | else | ||
447 | readsb (dma_base, hdr, sizeof (*hdr)); | ||
448 | |||
449 | writeb (ENISR_RDC, addr + EN0_ISR); | ||
450 | ei_local->dmaing = 0; | ||
451 | } | ||
452 | |||
453 | /* | ||
454 | * Open/initialize the board. This is called (in the current kernel) | ||
455 | * sometime after booting when the 'ifconfig' program is run. | ||
456 | * | ||
457 | * This routine should set everything up anew at each open, even | ||
458 | * registers that "should" only need to be set once at boot, so that | ||
459 | * there is non-reboot way to recover if something goes wrong. | ||
460 | */ | ||
461 | static int | ||
462 | etherh_open(struct net_device *dev) | ||
463 | { | ||
464 | struct ei_device *ei_local = netdev_priv(dev); | ||
465 | |||
466 | if (!is_valid_ether_addr(dev->dev_addr)) { | ||
467 | printk(KERN_WARNING "%s: invalid ethernet MAC address\n", | ||
468 | dev->name); | ||
469 | return -EINVAL; | ||
470 | } | ||
471 | |||
472 | if (request_irq(dev->irq, __ei_interrupt, 0, dev->name, dev)) | ||
473 | return -EAGAIN; | ||
474 | |||
475 | /* | ||
476 | * Make sure that we aren't going to change the | ||
477 | * media type on the next reset - we are about to | ||
478 | * do automedia manually now. | ||
479 | */ | ||
480 | ei_local->interface_num = 0; | ||
481 | |||
482 | /* | ||
483 | * If we are doing automedia detection, do it now. | ||
484 | * This is more reliable than the 8390's detection. | ||
485 | */ | ||
486 | if (dev->flags & IFF_AUTOMEDIA) { | ||
487 | dev->if_port = IF_PORT_10BASET; | ||
488 | etherh_setif(dev); | ||
489 | mdelay(1); | ||
490 | if (!etherh_getifstat(dev)) { | ||
491 | dev->if_port = IF_PORT_10BASE2; | ||
492 | etherh_setif(dev); | ||
493 | } | ||
494 | } else | ||
495 | etherh_setif(dev); | ||
496 | |||
497 | etherh_reset(dev); | ||
498 | __ei_open(dev); | ||
499 | |||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | /* | ||
504 | * The inverse routine to etherh_open(). | ||
505 | */ | ||
506 | static int | ||
507 | etherh_close(struct net_device *dev) | ||
508 | { | ||
509 | __ei_close (dev); | ||
510 | free_irq (dev->irq, dev); | ||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | /* | ||
515 | * Initialisation | ||
516 | */ | ||
517 | |||
518 | static void __init etherh_banner(void) | ||
519 | { | ||
520 | static int version_printed; | ||
521 | |||
522 | if (net_debug && version_printed++ == 0) | ||
523 | printk(KERN_INFO "%s", version); | ||
524 | } | ||
525 | |||
526 | /* | ||
527 | * Read the ethernet address string from the on board rom. | ||
528 | * This is an ascii string... | ||
529 | */ | ||
530 | static int __devinit etherh_addr(char *addr, struct expansion_card *ec) | ||
531 | { | ||
532 | struct in_chunk_dir cd; | ||
533 | char *s; | ||
534 | |||
535 | if (!ecard_readchunk(&cd, ec, 0xf5, 0)) { | ||
536 | printk(KERN_ERR "%s: unable to read podule description string\n", | ||
537 | dev_name(&ec->dev)); | ||
538 | goto no_addr; | ||
539 | } | ||
540 | |||
541 | s = strchr(cd.d.string, '('); | ||
542 | if (s) { | ||
543 | int i; | ||
544 | |||
545 | for (i = 0; i < 6; i++) { | ||
546 | addr[i] = simple_strtoul(s + 1, &s, 0x10); | ||
547 | if (*s != (i == 5? ')' : ':')) | ||
548 | break; | ||
549 | } | ||
550 | |||
551 | if (i == 6) | ||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | printk(KERN_ERR "%s: unable to parse MAC address: %s\n", | ||
556 | dev_name(&ec->dev), cd.d.string); | ||
557 | |||
558 | no_addr: | ||
559 | return -ENODEV; | ||
560 | } | ||
561 | |||
562 | /* | ||
563 | * Create an ethernet address from the system serial number. | ||
564 | */ | ||
565 | static int __init etherm_addr(char *addr) | ||
566 | { | ||
567 | unsigned int serial; | ||
568 | |||
569 | if (system_serial_low == 0 && system_serial_high == 0) | ||
570 | return -ENODEV; | ||
571 | |||
572 | serial = system_serial_low | system_serial_high; | ||
573 | |||
574 | addr[0] = 0; | ||
575 | addr[1] = 0; | ||
576 | addr[2] = 0xa4; | ||
577 | addr[3] = 0x10 + (serial >> 24); | ||
578 | addr[4] = serial >> 16; | ||
579 | addr[5] = serial >> 8; | ||
580 | return 0; | ||
581 | } | ||
582 | |||
583 | static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | ||
584 | { | ||
585 | strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); | ||
586 | strlcpy(info->version, DRV_VERSION, sizeof(info->version)); | ||
587 | strlcpy(info->bus_info, dev_name(dev->dev.parent), | ||
588 | sizeof(info->bus_info)); | ||
589 | } | ||
590 | |||
591 | static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
592 | { | ||
593 | cmd->supported = etherh_priv(dev)->supported; | ||
594 | ethtool_cmd_speed_set(cmd, SPEED_10); | ||
595 | cmd->duplex = DUPLEX_HALF; | ||
596 | cmd->port = dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC; | ||
597 | cmd->autoneg = (dev->flags & IFF_AUTOMEDIA ? | ||
598 | AUTONEG_ENABLE : AUTONEG_DISABLE); | ||
599 | return 0; | ||
600 | } | ||
601 | |||
602 | static int etherh_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
603 | { | ||
604 | switch (cmd->autoneg) { | ||
605 | case AUTONEG_ENABLE: | ||
606 | dev->flags |= IFF_AUTOMEDIA; | ||
607 | break; | ||
608 | |||
609 | case AUTONEG_DISABLE: | ||
610 | switch (cmd->port) { | ||
611 | case PORT_TP: | ||
612 | dev->if_port = IF_PORT_10BASET; | ||
613 | break; | ||
614 | |||
615 | case PORT_BNC: | ||
616 | dev->if_port = IF_PORT_10BASE2; | ||
617 | break; | ||
618 | |||
619 | default: | ||
620 | return -EINVAL; | ||
621 | } | ||
622 | dev->flags &= ~IFF_AUTOMEDIA; | ||
623 | break; | ||
624 | |||
625 | default: | ||
626 | return -EINVAL; | ||
627 | } | ||
628 | |||
629 | etherh_setif(dev); | ||
630 | |||
631 | return 0; | ||
632 | } | ||
633 | |||
634 | static const struct ethtool_ops etherh_ethtool_ops = { | ||
635 | .get_settings = etherh_get_settings, | ||
636 | .set_settings = etherh_set_settings, | ||
637 | .get_drvinfo = etherh_get_drvinfo, | ||
638 | }; | ||
639 | |||
640 | static const struct net_device_ops etherh_netdev_ops = { | ||
641 | .ndo_open = etherh_open, | ||
642 | .ndo_stop = etherh_close, | ||
643 | .ndo_set_config = etherh_set_config, | ||
644 | .ndo_start_xmit = __ei_start_xmit, | ||
645 | .ndo_tx_timeout = __ei_tx_timeout, | ||
646 | .ndo_get_stats = __ei_get_stats, | ||
647 | .ndo_set_multicast_list = __ei_set_multicast_list, | ||
648 | .ndo_validate_addr = eth_validate_addr, | ||
649 | .ndo_set_mac_address = eth_mac_addr, | ||
650 | .ndo_change_mtu = eth_change_mtu, | ||
651 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
652 | .ndo_poll_controller = __ei_poll, | ||
653 | #endif | ||
654 | }; | ||
655 | |||
656 | static u32 etherh_regoffsets[16]; | ||
657 | static u32 etherm_regoffsets[16]; | ||
658 | |||
659 | static int __devinit | ||
660 | etherh_probe(struct expansion_card *ec, const struct ecard_id *id) | ||
661 | { | ||
662 | const struct etherh_data *data = id->data; | ||
663 | struct ei_device *ei_local; | ||
664 | struct net_device *dev; | ||
665 | struct etherh_priv *eh; | ||
666 | int ret; | ||
667 | |||
668 | etherh_banner(); | ||
669 | |||
670 | ret = ecard_request_resources(ec); | ||
671 | if (ret) | ||
672 | goto out; | ||
673 | |||
674 | dev = ____alloc_ei_netdev(sizeof(struct etherh_priv)); | ||
675 | if (!dev) { | ||
676 | ret = -ENOMEM; | ||
677 | goto release; | ||
678 | } | ||
679 | |||
680 | SET_NETDEV_DEV(dev, &ec->dev); | ||
681 | |||
682 | dev->netdev_ops = ðerh_netdev_ops; | ||
683 | dev->irq = ec->irq; | ||
684 | dev->ethtool_ops = ðerh_ethtool_ops; | ||
685 | |||
686 | if (data->supported & SUPPORTED_Autoneg) | ||
687 | dev->flags |= IFF_AUTOMEDIA; | ||
688 | if (data->supported & SUPPORTED_TP) { | ||
689 | dev->flags |= IFF_PORTSEL; | ||
690 | dev->if_port = IF_PORT_10BASET; | ||
691 | } else if (data->supported & SUPPORTED_BNC) { | ||
692 | dev->flags |= IFF_PORTSEL; | ||
693 | dev->if_port = IF_PORT_10BASE2; | ||
694 | } else | ||
695 | dev->if_port = IF_PORT_UNKNOWN; | ||
696 | |||
697 | eh = etherh_priv(dev); | ||
698 | eh->supported = data->supported; | ||
699 | eh->ctrl = 0; | ||
700 | eh->id = ec->cid.product; | ||
701 | eh->memc = ecardm_iomap(ec, ECARD_RES_MEMC, 0, PAGE_SIZE); | ||
702 | if (!eh->memc) { | ||
703 | ret = -ENOMEM; | ||
704 | goto free; | ||
705 | } | ||
706 | |||
707 | eh->ctrl_port = eh->memc; | ||
708 | if (data->ctrl_ioc) { | ||
709 | eh->ioc_fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, PAGE_SIZE); | ||
710 | if (!eh->ioc_fast) { | ||
711 | ret = -ENOMEM; | ||
712 | goto free; | ||
713 | } | ||
714 | eh->ctrl_port = eh->ioc_fast; | ||
715 | } | ||
716 | |||
717 | dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset; | ||
718 | eh->dma_base = eh->memc + data->dataport_offset; | ||
719 | eh->ctrl_port += data->ctrlport_offset; | ||
720 | |||
721 | /* | ||
722 | * IRQ and control port handling - only for non-NIC slot cards. | ||
723 | */ | ||
724 | if (ec->slot_no != 8) { | ||
725 | ecard_setirq(ec, ðerh_ops, eh); | ||
726 | } else { | ||
727 | /* | ||
728 | * If we're in the NIC slot, make sure the IRQ is enabled | ||
729 | */ | ||
730 | etherh_set_ctrl(eh, ETHERH_CP_IE); | ||
731 | } | ||
732 | |||
733 | ei_local = netdev_priv(dev); | ||
734 | spin_lock_init(&ei_local->page_lock); | ||
735 | |||
736 | if (ec->cid.product == PROD_ANT_ETHERM) { | ||
737 | etherm_addr(dev->dev_addr); | ||
738 | ei_local->reg_offset = etherm_regoffsets; | ||
739 | } else { | ||
740 | etherh_addr(dev->dev_addr, ec); | ||
741 | ei_local->reg_offset = etherh_regoffsets; | ||
742 | } | ||
743 | |||
744 | ei_local->name = dev->name; | ||
745 | ei_local->word16 = 1; | ||
746 | ei_local->tx_start_page = data->tx_start_page; | ||
747 | ei_local->rx_start_page = ei_local->tx_start_page + TX_PAGES; | ||
748 | ei_local->stop_page = data->stop_page; | ||
749 | ei_local->reset_8390 = etherh_reset; | ||
750 | ei_local->block_input = etherh_block_input; | ||
751 | ei_local->block_output = etherh_block_output; | ||
752 | ei_local->get_8390_hdr = etherh_get_header; | ||
753 | ei_local->interface_num = 0; | ||
754 | |||
755 | etherh_reset(dev); | ||
756 | __NS8390_init(dev, 0); | ||
757 | |||
758 | ret = register_netdev(dev); | ||
759 | if (ret) | ||
760 | goto free; | ||
761 | |||
762 | printk(KERN_INFO "%s: %s in slot %d, %pM\n", | ||
763 | dev->name, data->name, ec->slot_no, dev->dev_addr); | ||
764 | |||
765 | ecard_set_drvdata(ec, dev); | ||
766 | |||
767 | return 0; | ||
768 | |||
769 | free: | ||
770 | free_netdev(dev); | ||
771 | release: | ||
772 | ecard_release_resources(ec); | ||
773 | out: | ||
774 | return ret; | ||
775 | } | ||
776 | |||
777 | static void __devexit etherh_remove(struct expansion_card *ec) | ||
778 | { | ||
779 | struct net_device *dev = ecard_get_drvdata(ec); | ||
780 | |||
781 | ecard_set_drvdata(ec, NULL); | ||
782 | |||
783 | unregister_netdev(dev); | ||
784 | |||
785 | free_netdev(dev); | ||
786 | |||
787 | ecard_release_resources(ec); | ||
788 | } | ||
789 | |||
790 | static struct etherh_data etherm_data = { | ||
791 | .ns8390_offset = ETHERM_NS8390, | ||
792 | .dataport_offset = ETHERM_NS8390 + ETHERM_DATAPORT, | ||
793 | .ctrlport_offset = ETHERM_NS8390 + ETHERM_CTRLPORT, | ||
794 | .name = "ANT EtherM", | ||
795 | .supported = SUPPORTED_10baseT_Half, | ||
796 | .tx_start_page = ETHERM_TX_START_PAGE, | ||
797 | .stop_page = ETHERM_STOP_PAGE, | ||
798 | }; | ||
799 | |||
800 | static struct etherh_data etherlan500_data = { | ||
801 | .ns8390_offset = ETHERH500_NS8390, | ||
802 | .dataport_offset = ETHERH500_NS8390 + ETHERH500_DATAPORT, | ||
803 | .ctrlport_offset = ETHERH500_CTRLPORT, | ||
804 | .ctrl_ioc = 1, | ||
805 | .name = "i3 EtherH 500", | ||
806 | .supported = SUPPORTED_10baseT_Half, | ||
807 | .tx_start_page = ETHERH_TX_START_PAGE, | ||
808 | .stop_page = ETHERH_STOP_PAGE, | ||
809 | }; | ||
810 | |||
811 | static struct etherh_data etherlan600_data = { | ||
812 | .ns8390_offset = ETHERH600_NS8390, | ||
813 | .dataport_offset = ETHERH600_NS8390 + ETHERH600_DATAPORT, | ||
814 | .ctrlport_offset = ETHERH600_NS8390 + ETHERH600_CTRLPORT, | ||
815 | .name = "i3 EtherH 600", | ||
816 | .supported = SUPPORTED_10baseT_Half | SUPPORTED_TP | SUPPORTED_BNC | SUPPORTED_Autoneg, | ||
817 | .tx_start_page = ETHERH_TX_START_PAGE, | ||
818 | .stop_page = ETHERH_STOP_PAGE, | ||
819 | }; | ||
820 | |||
821 | static struct etherh_data etherlan600a_data = { | ||
822 | .ns8390_offset = ETHERH600_NS8390, | ||
823 | .dataport_offset = ETHERH600_NS8390 + ETHERH600_DATAPORT, | ||
824 | .ctrlport_offset = ETHERH600_NS8390 + ETHERH600_CTRLPORT, | ||
825 | .name = "i3 EtherH 600A", | ||
826 | .supported = SUPPORTED_10baseT_Half | SUPPORTED_TP | SUPPORTED_BNC | SUPPORTED_Autoneg, | ||
827 | .tx_start_page = ETHERH_TX_START_PAGE, | ||
828 | .stop_page = ETHERH_STOP_PAGE, | ||
829 | }; | ||
830 | |||
831 | static const struct ecard_id etherh_ids[] = { | ||
832 | { MANU_ANT, PROD_ANT_ETHERM, ðerm_data }, | ||
833 | { MANU_I3, PROD_I3_ETHERLAN500, ðerlan500_data }, | ||
834 | { MANU_I3, PROD_I3_ETHERLAN600, ðerlan600_data }, | ||
835 | { MANU_I3, PROD_I3_ETHERLAN600A, ðerlan600a_data }, | ||
836 | { 0xffff, 0xffff } | ||
837 | }; | ||
838 | |||
839 | static struct ecard_driver etherh_driver = { | ||
840 | .probe = etherh_probe, | ||
841 | .remove = __devexit_p(etherh_remove), | ||
842 | .id_table = etherh_ids, | ||
843 | .drv = { | ||
844 | .name = DRV_NAME, | ||
845 | }, | ||
846 | }; | ||
847 | |||
848 | static int __init etherh_init(void) | ||
849 | { | ||
850 | int i; | ||
851 | |||
852 | for (i = 0; i < 16; i++) { | ||
853 | etherh_regoffsets[i] = i << 2; | ||
854 | etherm_regoffsets[i] = i << 5; | ||
855 | } | ||
856 | |||
857 | return ecard_register_driver(ðerh_driver); | ||
858 | } | ||
859 | |||
860 | static void __exit etherh_exit(void) | ||
861 | { | ||
862 | ecard_remove_driver(ðerh_driver); | ||
863 | } | ||
864 | |||
865 | module_init(etherh_init); | ||
866 | module_exit(etherh_exit); | ||
diff --git a/drivers/net/ethernet/8390/hp-plus.c b/drivers/net/ethernet/8390/hp-plus.c new file mode 100644 index 000000000000..29917363ebfb --- /dev/null +++ b/drivers/net/ethernet/8390/hp-plus.c | |||
@@ -0,0 +1,506 @@ | |||
1 | /* hp-plus.c: A HP PCLAN/plus ethernet driver for linux. */ | ||
2 | /* | ||
3 | Written 1994 by Donald Becker. | ||
4 | |||
5 | This driver is for the Hewlett Packard PC LAN (27***) plus ethercards. | ||
6 | These cards are sold under several model numbers, usually 2724*. | ||
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 | As is often the case, a great deal of credit is owed to Russ Nelson. | ||
17 | The Crynwr packet driver was my primary source of HP-specific | ||
18 | programming information. | ||
19 | */ | ||
20 | |||
21 | static const char version[] = | ||
22 | "hp-plus.c:v1.10 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | |||
26 | #include <linux/string.h> /* Important -- this inlines word moves. */ | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/ioport.h> | ||
30 | #include <linux/netdevice.h> | ||
31 | #include <linux/etherdevice.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <linux/delay.h> | ||
35 | |||
36 | #include <asm/system.h> | ||
37 | #include <asm/io.h> | ||
38 | |||
39 | #include "8390.h" | ||
40 | |||
41 | #define DRV_NAME "hp-plus" | ||
42 | |||
43 | /* A zero-terminated list of I/O addresses to be probed. */ | ||
44 | static unsigned int hpplus_portlist[] __initdata = | ||
45 | {0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0}; | ||
46 | |||
47 | /* | ||
48 | The HP EtherTwist chip implementation is a fairly routine DP8390 | ||
49 | implementation. It allows both shared memory and programmed-I/O buffer | ||
50 | access, using a custom interface for both. The programmed-I/O mode is | ||
51 | entirely implemented in the HP EtherTwist chip, bypassing the problem | ||
52 | ridden built-in 8390 facilities used on NE2000 designs. The shared | ||
53 | memory mode is likewise special, with an offset register used to make | ||
54 | packets appear at the shared memory base. Both modes use a base and bounds | ||
55 | page register to hide the Rx ring buffer wrap -- a packet that spans the | ||
56 | end of physical buffer memory appears continuous to the driver. (c.f. the | ||
57 | 3c503 and Cabletron E2100) | ||
58 | |||
59 | A special note: the internal buffer of the board is only 8 bits wide. | ||
60 | This lays several nasty traps for the unaware: | ||
61 | - the 8390 must be programmed for byte-wide operations | ||
62 | - all I/O and memory operations must work on whole words (the access | ||
63 | latches are serially preloaded and have no byte-swapping ability). | ||
64 | |||
65 | This board is laid out in I/O space much like the earlier HP boards: | ||
66 | the first 16 locations are for the board registers, and the second 16 are | ||
67 | for the 8390. The board is easy to identify, with both a dedicated 16 bit | ||
68 | ID register and a constant 0x530* value in the upper bits of the paging | ||
69 | register. | ||
70 | */ | ||
71 | |||
72 | #define HP_ID 0x00 /* ID register, always 0x4850. */ | ||
73 | #define HP_PAGING 0x02 /* Registers visible @ 8-f, see PageName. */ | ||
74 | #define HPP_OPTION 0x04 /* Bitmapped options, see HP_Option. */ | ||
75 | #define HPP_OUT_ADDR 0x08 /* I/O output location in Perf_Page. */ | ||
76 | #define HPP_IN_ADDR 0x0A /* I/O input location in Perf_Page. */ | ||
77 | #define HP_DATAPORT 0x0c /* I/O data transfer in Perf_Page. */ | ||
78 | #define NIC_OFFSET 0x10 /* Offset to the 8390 registers. */ | ||
79 | #define HP_IO_EXTENT 32 | ||
80 | |||
81 | #define HP_START_PG 0x00 /* First page of TX buffer */ | ||
82 | #define HP_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
83 | |||
84 | /* The register set selected in HP_PAGING. */ | ||
85 | enum PageName { | ||
86 | Perf_Page = 0, /* Normal operation. */ | ||
87 | MAC_Page = 1, /* The ethernet address (+checksum). */ | ||
88 | HW_Page = 2, /* EEPROM-loaded hardware parameters. */ | ||
89 | LAN_Page = 4, /* Transceiver selection, testing, etc. */ | ||
90 | ID_Page = 6 }; | ||
91 | |||
92 | /* The bit definitions for the HPP_OPTION register. */ | ||
93 | enum HP_Option { | ||
94 | NICReset = 1, ChipReset = 2, /* Active low, really UNreset. */ | ||
95 | EnableIRQ = 4, FakeIntr = 8, BootROMEnb = 0x10, IOEnb = 0x20, | ||
96 | MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, }; | ||
97 | |||
98 | static int hpp_probe1(struct net_device *dev, int ioaddr); | ||
99 | |||
100 | static void hpp_reset_8390(struct net_device *dev); | ||
101 | static int hpp_open(struct net_device *dev); | ||
102 | static int hpp_close(struct net_device *dev); | ||
103 | static void hpp_mem_block_input(struct net_device *dev, int count, | ||
104 | struct sk_buff *skb, int ring_offset); | ||
105 | static void hpp_mem_block_output(struct net_device *dev, int count, | ||
106 | const unsigned char *buf, int start_page); | ||
107 | static void hpp_mem_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
108 | int ring_page); | ||
109 | static void hpp_io_block_input(struct net_device *dev, int count, | ||
110 | struct sk_buff *skb, int ring_offset); | ||
111 | static void hpp_io_block_output(struct net_device *dev, int count, | ||
112 | const unsigned char *buf, int start_page); | ||
113 | static void hpp_io_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
114 | int ring_page); | ||
115 | |||
116 | |||
117 | /* Probe a list of addresses for an HP LAN+ adaptor. | ||
118 | This routine is almost boilerplate. */ | ||
119 | |||
120 | static int __init do_hpp_probe(struct net_device *dev) | ||
121 | { | ||
122 | int i; | ||
123 | int base_addr = dev->base_addr; | ||
124 | int irq = dev->irq; | ||
125 | |||
126 | if (base_addr > 0x1ff) /* Check a single specified location. */ | ||
127 | return hpp_probe1(dev, base_addr); | ||
128 | else if (base_addr != 0) /* Don't probe at all. */ | ||
129 | return -ENXIO; | ||
130 | |||
131 | for (i = 0; hpplus_portlist[i]; i++) { | ||
132 | if (hpp_probe1(dev, hpplus_portlist[i]) == 0) | ||
133 | return 0; | ||
134 | dev->irq = irq; | ||
135 | } | ||
136 | |||
137 | return -ENODEV; | ||
138 | } | ||
139 | |||
140 | #ifndef MODULE | ||
141 | struct net_device * __init hp_plus_probe(int unit) | ||
142 | { | ||
143 | struct net_device *dev = alloc_eip_netdev(); | ||
144 | int err; | ||
145 | |||
146 | if (!dev) | ||
147 | return ERR_PTR(-ENOMEM); | ||
148 | |||
149 | sprintf(dev->name, "eth%d", unit); | ||
150 | netdev_boot_setup_check(dev); | ||
151 | |||
152 | err = do_hpp_probe(dev); | ||
153 | if (err) | ||
154 | goto out; | ||
155 | return dev; | ||
156 | out: | ||
157 | free_netdev(dev); | ||
158 | return ERR_PTR(err); | ||
159 | } | ||
160 | #endif | ||
161 | |||
162 | static const struct net_device_ops hpp_netdev_ops = { | ||
163 | .ndo_open = hpp_open, | ||
164 | .ndo_stop = hpp_close, | ||
165 | .ndo_start_xmit = eip_start_xmit, | ||
166 | .ndo_tx_timeout = eip_tx_timeout, | ||
167 | .ndo_get_stats = eip_get_stats, | ||
168 | .ndo_set_multicast_list = eip_set_multicast_list, | ||
169 | .ndo_validate_addr = eth_validate_addr, | ||
170 | .ndo_set_mac_address = eth_mac_addr, | ||
171 | .ndo_change_mtu = eth_change_mtu, | ||
172 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
173 | .ndo_poll_controller = eip_poll, | ||
174 | #endif | ||
175 | }; | ||
176 | |||
177 | |||
178 | /* Do the interesting part of the probe at a single address. */ | ||
179 | static int __init hpp_probe1(struct net_device *dev, int ioaddr) | ||
180 | { | ||
181 | int i, retval; | ||
182 | unsigned char checksum = 0; | ||
183 | const char name[] = "HP-PC-LAN+"; | ||
184 | int mem_start; | ||
185 | static unsigned version_printed; | ||
186 | |||
187 | if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME)) | ||
188 | return -EBUSY; | ||
189 | |||
190 | /* Check for the HP+ signature, 50 48 0x 53. */ | ||
191 | if (inw(ioaddr + HP_ID) != 0x4850 || | ||
192 | (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300) { | ||
193 | retval = -ENODEV; | ||
194 | goto out; | ||
195 | } | ||
196 | |||
197 | if (ei_debug && version_printed++ == 0) | ||
198 | printk(version); | ||
199 | |||
200 | printk("%s: %s at %#3x, ", dev->name, name, ioaddr); | ||
201 | |||
202 | /* Retrieve and checksum the station address. */ | ||
203 | outw(MAC_Page, ioaddr + HP_PAGING); | ||
204 | |||
205 | for(i = 0; i < ETHER_ADDR_LEN; i++) { | ||
206 | unsigned char inval = inb(ioaddr + 8 + i); | ||
207 | dev->dev_addr[i] = inval; | ||
208 | checksum += inval; | ||
209 | } | ||
210 | checksum += inb(ioaddr + 14); | ||
211 | |||
212 | printk("%pM", dev->dev_addr); | ||
213 | |||
214 | if (checksum != 0xff) { | ||
215 | printk(" bad checksum %2.2x.\n", checksum); | ||
216 | retval = -ENODEV; | ||
217 | goto out; | ||
218 | } else { | ||
219 | /* Point at the Software Configuration Flags. */ | ||
220 | outw(ID_Page, ioaddr + HP_PAGING); | ||
221 | printk(" ID %4.4x", inw(ioaddr + 12)); | ||
222 | } | ||
223 | |||
224 | /* Read the IRQ line. */ | ||
225 | outw(HW_Page, ioaddr + HP_PAGING); | ||
226 | { | ||
227 | int irq = inb(ioaddr + 13) & 0x0f; | ||
228 | int option = inw(ioaddr + HPP_OPTION); | ||
229 | |||
230 | dev->irq = irq; | ||
231 | if (option & MemEnable) { | ||
232 | mem_start = inw(ioaddr + 9) << 8; | ||
233 | printk(", IRQ %d, memory address %#x.\n", irq, mem_start); | ||
234 | } else { | ||
235 | mem_start = 0; | ||
236 | printk(", IRQ %d, programmed-I/O mode.\n", irq); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | /* Set the wrap registers for string I/O reads. */ | ||
241 | outw((HP_START_PG + TX_PAGES/2) | ((HP_STOP_PG - 1) << 8), ioaddr + 14); | ||
242 | |||
243 | /* Set the base address to point to the NIC, not the "real" base! */ | ||
244 | dev->base_addr = ioaddr + NIC_OFFSET; | ||
245 | |||
246 | dev->netdev_ops = &hpp_netdev_ops; | ||
247 | |||
248 | ei_status.name = name; | ||
249 | ei_status.word16 = 0; /* Agggghhhhh! Debug time: 2 days! */ | ||
250 | ei_status.tx_start_page = HP_START_PG; | ||
251 | ei_status.rx_start_page = HP_START_PG + TX_PAGES/2; | ||
252 | ei_status.stop_page = HP_STOP_PG; | ||
253 | |||
254 | ei_status.reset_8390 = &hpp_reset_8390; | ||
255 | ei_status.block_input = &hpp_io_block_input; | ||
256 | ei_status.block_output = &hpp_io_block_output; | ||
257 | ei_status.get_8390_hdr = &hpp_io_get_8390_hdr; | ||
258 | |||
259 | /* Check if the memory_enable flag is set in the option register. */ | ||
260 | if (mem_start) { | ||
261 | ei_status.block_input = &hpp_mem_block_input; | ||
262 | ei_status.block_output = &hpp_mem_block_output; | ||
263 | ei_status.get_8390_hdr = &hpp_mem_get_8390_hdr; | ||
264 | dev->mem_start = mem_start; | ||
265 | ei_status.mem = ioremap(mem_start, | ||
266 | (HP_STOP_PG - HP_START_PG)*256); | ||
267 | if (!ei_status.mem) { | ||
268 | retval = -ENOMEM; | ||
269 | goto out; | ||
270 | } | ||
271 | ei_status.rmem_start = dev->mem_start + TX_PAGES/2*256; | ||
272 | dev->mem_end = ei_status.rmem_end | ||
273 | = dev->mem_start + (HP_STOP_PG - HP_START_PG)*256; | ||
274 | } | ||
275 | |||
276 | outw(Perf_Page, ioaddr + HP_PAGING); | ||
277 | NS8390p_init(dev, 0); | ||
278 | /* Leave the 8390 and HP chip reset. */ | ||
279 | outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION); | ||
280 | |||
281 | retval = register_netdev(dev); | ||
282 | if (retval) | ||
283 | goto out1; | ||
284 | return 0; | ||
285 | out1: | ||
286 | iounmap(ei_status.mem); | ||
287 | out: | ||
288 | release_region(ioaddr, HP_IO_EXTENT); | ||
289 | return retval; | ||
290 | } | ||
291 | |||
292 | static int | ||
293 | hpp_open(struct net_device *dev) | ||
294 | { | ||
295 | int ioaddr = dev->base_addr - NIC_OFFSET; | ||
296 | int option_reg; | ||
297 | int retval; | ||
298 | |||
299 | if ((retval = request_irq(dev->irq, eip_interrupt, 0, dev->name, dev))) { | ||
300 | return retval; | ||
301 | } | ||
302 | |||
303 | /* Reset the 8390 and HP chip. */ | ||
304 | option_reg = inw(ioaddr + HPP_OPTION); | ||
305 | outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION); | ||
306 | udelay(5); | ||
307 | /* Unreset the board and enable interrupts. */ | ||
308 | outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION); | ||
309 | |||
310 | /* Set the wrap registers for programmed-I/O operation. */ | ||
311 | outw(HW_Page, ioaddr + HP_PAGING); | ||
312 | outw((HP_START_PG + TX_PAGES/2) | ((HP_STOP_PG - 1) << 8), ioaddr + 14); | ||
313 | |||
314 | /* Select the operational page. */ | ||
315 | outw(Perf_Page, ioaddr + HP_PAGING); | ||
316 | |||
317 | return eip_open(dev); | ||
318 | } | ||
319 | |||
320 | static int | ||
321 | hpp_close(struct net_device *dev) | ||
322 | { | ||
323 | int ioaddr = dev->base_addr - NIC_OFFSET; | ||
324 | int option_reg = inw(ioaddr + HPP_OPTION); | ||
325 | |||
326 | free_irq(dev->irq, dev); | ||
327 | eip_close(dev); | ||
328 | outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset, | ||
329 | ioaddr + HPP_OPTION); | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | static void | ||
335 | hpp_reset_8390(struct net_device *dev) | ||
336 | { | ||
337 | int ioaddr = dev->base_addr - NIC_OFFSET; | ||
338 | int option_reg = inw(ioaddr + HPP_OPTION); | ||
339 | |||
340 | if (ei_debug > 1) printk("resetting the 8390 time=%ld...", jiffies); | ||
341 | |||
342 | outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION); | ||
343 | /* Pause a few cycles for the hardware reset to take place. */ | ||
344 | udelay(5); | ||
345 | ei_status.txing = 0; | ||
346 | outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION); | ||
347 | |||
348 | udelay(5); | ||
349 | |||
350 | |||
351 | if ((inb_p(ioaddr+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0) | ||
352 | printk("%s: hp_reset_8390() did not complete.\n", dev->name); | ||
353 | |||
354 | if (ei_debug > 1) printk("8390 reset done (%ld).", jiffies); | ||
355 | } | ||
356 | |||
357 | /* The programmed-I/O version of reading the 4 byte 8390 specific header. | ||
358 | Note that transfer with the EtherTwist+ must be on word boundaries. */ | ||
359 | |||
360 | static void | ||
361 | hpp_io_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
362 | { | ||
363 | int ioaddr = dev->base_addr - NIC_OFFSET; | ||
364 | |||
365 | outw((ring_page<<8), ioaddr + HPP_IN_ADDR); | ||
366 | insw(ioaddr + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1); | ||
367 | } | ||
368 | |||
369 | /* Block input and output, similar to the Crynwr packet driver. */ | ||
370 | |||
371 | static void | ||
372 | hpp_io_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
373 | { | ||
374 | int ioaddr = dev->base_addr - NIC_OFFSET; | ||
375 | char *buf = skb->data; | ||
376 | |||
377 | outw(ring_offset, ioaddr + HPP_IN_ADDR); | ||
378 | insw(ioaddr + HP_DATAPORT, buf, count>>1); | ||
379 | if (count & 0x01) | ||
380 | buf[count-1] = inw(ioaddr + HP_DATAPORT); | ||
381 | } | ||
382 | |||
383 | /* The corresponding shared memory versions of the above 2 functions. */ | ||
384 | |||
385 | static void | ||
386 | hpp_mem_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
387 | { | ||
388 | int ioaddr = dev->base_addr - NIC_OFFSET; | ||
389 | int option_reg = inw(ioaddr + HPP_OPTION); | ||
390 | |||
391 | outw((ring_page<<8), ioaddr + HPP_IN_ADDR); | ||
392 | outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION); | ||
393 | memcpy_fromio(hdr, ei_status.mem, sizeof(struct e8390_pkt_hdr)); | ||
394 | outw(option_reg, ioaddr + HPP_OPTION); | ||
395 | hdr->count = (le16_to_cpu(hdr->count) + 3) & ~3; /* Round up allocation. */ | ||
396 | } | ||
397 | |||
398 | static void | ||
399 | hpp_mem_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
400 | { | ||
401 | int ioaddr = dev->base_addr - NIC_OFFSET; | ||
402 | int option_reg = inw(ioaddr + HPP_OPTION); | ||
403 | |||
404 | outw(ring_offset, ioaddr + HPP_IN_ADDR); | ||
405 | |||
406 | outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION); | ||
407 | |||
408 | /* Caution: this relies on get_8390_hdr() rounding up count! | ||
409 | Also note that we *can't* use eth_io_copy_and_sum() because | ||
410 | it will not always copy "count" bytes (e.g. padded IP). */ | ||
411 | |||
412 | memcpy_fromio(skb->data, ei_status.mem, count); | ||
413 | outw(option_reg, ioaddr + HPP_OPTION); | ||
414 | } | ||
415 | |||
416 | /* A special note: we *must* always transfer >=16 bit words. | ||
417 | It's always safe to round up, so we do. */ | ||
418 | static void | ||
419 | hpp_io_block_output(struct net_device *dev, int count, | ||
420 | const unsigned char *buf, int start_page) | ||
421 | { | ||
422 | int ioaddr = dev->base_addr - NIC_OFFSET; | ||
423 | outw(start_page << 8, ioaddr + HPP_OUT_ADDR); | ||
424 | outsl(ioaddr + HP_DATAPORT, buf, (count+3)>>2); | ||
425 | } | ||
426 | |||
427 | static void | ||
428 | hpp_mem_block_output(struct net_device *dev, int count, | ||
429 | const unsigned char *buf, int start_page) | ||
430 | { | ||
431 | int ioaddr = dev->base_addr - NIC_OFFSET; | ||
432 | int option_reg = inw(ioaddr + HPP_OPTION); | ||
433 | |||
434 | outw(start_page << 8, ioaddr + HPP_OUT_ADDR); | ||
435 | outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION); | ||
436 | memcpy_toio(ei_status.mem, buf, (count + 3) & ~3); | ||
437 | outw(option_reg, ioaddr + HPP_OPTION); | ||
438 | } | ||
439 | |||
440 | |||
441 | #ifdef MODULE | ||
442 | #define MAX_HPP_CARDS 4 /* Max number of HPP cards per module */ | ||
443 | static struct net_device *dev_hpp[MAX_HPP_CARDS]; | ||
444 | static int io[MAX_HPP_CARDS]; | ||
445 | static int irq[MAX_HPP_CARDS]; | ||
446 | |||
447 | module_param_array(io, int, NULL, 0); | ||
448 | module_param_array(irq, int, NULL, 0); | ||
449 | MODULE_PARM_DESC(io, "I/O port address(es)"); | ||
450 | MODULE_PARM_DESC(irq, "IRQ number(s); ignored if properly detected"); | ||
451 | MODULE_DESCRIPTION("HP PC-LAN+ ISA ethernet driver"); | ||
452 | MODULE_LICENSE("GPL"); | ||
453 | |||
454 | /* This is set up so that only a single autoprobe takes place per call. | ||
455 | ISA device autoprobes on a running machine are not recommended. */ | ||
456 | int __init | ||
457 | init_module(void) | ||
458 | { | ||
459 | struct net_device *dev; | ||
460 | int this_dev, found = 0; | ||
461 | |||
462 | for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) { | ||
463 | if (io[this_dev] == 0) { | ||
464 | if (this_dev != 0) break; /* only autoprobe 1st one */ | ||
465 | printk(KERN_NOTICE "hp-plus.c: Presently autoprobing (not recommended) for a single card.\n"); | ||
466 | } | ||
467 | dev = alloc_eip_netdev(); | ||
468 | if (!dev) | ||
469 | break; | ||
470 | dev->irq = irq[this_dev]; | ||
471 | dev->base_addr = io[this_dev]; | ||
472 | if (do_hpp_probe(dev) == 0) { | ||
473 | dev_hpp[found++] = dev; | ||
474 | continue; | ||
475 | } | ||
476 | free_netdev(dev); | ||
477 | printk(KERN_WARNING "hp-plus.c: No HP-Plus card found (i/o = 0x%x).\n", io[this_dev]); | ||
478 | break; | ||
479 | } | ||
480 | if (found) | ||
481 | return 0; | ||
482 | return -ENXIO; | ||
483 | } | ||
484 | |||
485 | static void cleanup_card(struct net_device *dev) | ||
486 | { | ||
487 | /* NB: hpp_close() handles free_irq */ | ||
488 | iounmap(ei_status.mem); | ||
489 | release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT); | ||
490 | } | ||
491 | |||
492 | void __exit | ||
493 | cleanup_module(void) | ||
494 | { | ||
495 | int this_dev; | ||
496 | |||
497 | for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) { | ||
498 | struct net_device *dev = dev_hpp[this_dev]; | ||
499 | if (dev) { | ||
500 | unregister_netdev(dev); | ||
501 | cleanup_card(dev); | ||
502 | free_netdev(dev); | ||
503 | } | ||
504 | } | ||
505 | } | ||
506 | #endif /* MODULE */ | ||
diff --git a/drivers/net/ethernet/8390/hp.c b/drivers/net/ethernet/8390/hp.c new file mode 100644 index 000000000000..18564d4a7c04 --- /dev/null +++ b/drivers/net/ethernet/8390/hp.c | |||
@@ -0,0 +1,439 @@ | |||
1 | /* hp.c: A HP LAN ethernet driver for linux. */ | ||
2 | /* | ||
3 | Written 1993-94 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 | This is a driver for the HP PC-LAN adaptors. | ||
17 | |||
18 | Sources: | ||
19 | The Crynwr packet driver. | ||
20 | */ | ||
21 | |||
22 | static const char version[] = | ||
23 | "hp.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; | ||
24 | |||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/ioport.h> | ||
30 | #include <linux/netdevice.h> | ||
31 | #include <linux/etherdevice.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/interrupt.h> | ||
34 | #include <linux/delay.h> | ||
35 | |||
36 | #include <asm/system.h> | ||
37 | #include <asm/io.h> | ||
38 | |||
39 | #include "8390.h" | ||
40 | |||
41 | #define DRV_NAME "hp" | ||
42 | |||
43 | /* A zero-terminated list of I/O addresses to be probed. */ | ||
44 | static unsigned int hppclan_portlist[] __initdata = | ||
45 | { 0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240, 0}; | ||
46 | |||
47 | #define HP_IO_EXTENT 32 | ||
48 | |||
49 | #define HP_DATAPORT 0x0c /* "Remote DMA" data port. */ | ||
50 | #define HP_ID 0x07 | ||
51 | #define HP_CONFIGURE 0x08 /* Configuration register. */ | ||
52 | #define HP_RUN 0x01 /* 1 == Run, 0 == reset. */ | ||
53 | #define HP_IRQ 0x0E /* Mask for software-configured IRQ line. */ | ||
54 | #define HP_DATAON 0x10 /* Turn on dataport */ | ||
55 | #define NIC_OFFSET 0x10 /* Offset the 8390 registers. */ | ||
56 | |||
57 | #define HP_START_PG 0x00 /* First page of TX buffer */ | ||
58 | #define HP_8BSTOP_PG 0x80 /* Last page +1 of RX ring */ | ||
59 | #define HP_16BSTOP_PG 0xFF /* Same, for 16 bit cards. */ | ||
60 | |||
61 | static int hp_probe1(struct net_device *dev, int ioaddr); | ||
62 | |||
63 | static void hp_reset_8390(struct net_device *dev); | ||
64 | static void hp_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
65 | int ring_page); | ||
66 | static void hp_block_input(struct net_device *dev, int count, | ||
67 | struct sk_buff *skb , int ring_offset); | ||
68 | static void hp_block_output(struct net_device *dev, int count, | ||
69 | const unsigned char *buf, int start_page); | ||
70 | |||
71 | static void hp_init_card(struct net_device *dev); | ||
72 | |||
73 | /* The map from IRQ number to HP_CONFIGURE register setting. */ | ||
74 | /* My default is IRQ5 0 1 2 3 4 5 6 7 8 9 10 11 */ | ||
75 | static char irqmap[16] __initdata= { 0, 0, 4, 6, 8,10, 0,14, 0, 4, 2,12,0,0,0,0}; | ||
76 | |||
77 | |||
78 | /* Probe for an HP LAN adaptor. | ||
79 | Also initialize the card and fill in STATION_ADDR with the station | ||
80 | address. */ | ||
81 | |||
82 | static int __init do_hp_probe(struct net_device *dev) | ||
83 | { | ||
84 | int i; | ||
85 | int base_addr = dev->base_addr; | ||
86 | int irq = dev->irq; | ||
87 | |||
88 | if (base_addr > 0x1ff) /* Check a single specified location. */ | ||
89 | return hp_probe1(dev, base_addr); | ||
90 | else if (base_addr != 0) /* Don't probe at all. */ | ||
91 | return -ENXIO; | ||
92 | |||
93 | for (i = 0; hppclan_portlist[i]; i++) { | ||
94 | if (hp_probe1(dev, hppclan_portlist[i]) == 0) | ||
95 | return 0; | ||
96 | dev->irq = irq; | ||
97 | } | ||
98 | |||
99 | return -ENODEV; | ||
100 | } | ||
101 | |||
102 | #ifndef MODULE | ||
103 | struct net_device * __init hp_probe(int unit) | ||
104 | { | ||
105 | struct net_device *dev = alloc_eip_netdev(); | ||
106 | int err; | ||
107 | |||
108 | if (!dev) | ||
109 | return ERR_PTR(-ENOMEM); | ||
110 | |||
111 | sprintf(dev->name, "eth%d", unit); | ||
112 | netdev_boot_setup_check(dev); | ||
113 | |||
114 | err = do_hp_probe(dev); | ||
115 | if (err) | ||
116 | goto out; | ||
117 | return dev; | ||
118 | out: | ||
119 | free_netdev(dev); | ||
120 | return ERR_PTR(err); | ||
121 | } | ||
122 | #endif | ||
123 | |||
124 | static int __init hp_probe1(struct net_device *dev, int ioaddr) | ||
125 | { | ||
126 | int i, retval, board_id, wordmode; | ||
127 | const char *name; | ||
128 | static unsigned version_printed; | ||
129 | |||
130 | if (!request_region(ioaddr, HP_IO_EXTENT, DRV_NAME)) | ||
131 | return -EBUSY; | ||
132 | |||
133 | /* Check for the HP physical address, 08 00 09 xx xx xx. */ | ||
134 | /* This really isn't good enough: we may pick up HP LANCE boards | ||
135 | also! Avoid the lance 0x5757 signature. */ | ||
136 | if (inb(ioaddr) != 0x08 | ||
137 | || inb(ioaddr+1) != 0x00 | ||
138 | || inb(ioaddr+2) != 0x09 | ||
139 | || inb(ioaddr+14) == 0x57) { | ||
140 | retval = -ENODEV; | ||
141 | goto out; | ||
142 | } | ||
143 | |||
144 | /* Set up the parameters based on the board ID. | ||
145 | If you have additional mappings, please mail them to me -djb. */ | ||
146 | if ((board_id = inb(ioaddr + HP_ID)) & 0x80) { | ||
147 | name = "HP27247"; | ||
148 | wordmode = 1; | ||
149 | } else { | ||
150 | name = "HP27250"; | ||
151 | wordmode = 0; | ||
152 | } | ||
153 | |||
154 | if (ei_debug && version_printed++ == 0) | ||
155 | printk(version); | ||
156 | |||
157 | printk("%s: %s (ID %02x) at %#3x,", dev->name, name, board_id, ioaddr); | ||
158 | |||
159 | for(i = 0; i < ETHER_ADDR_LEN; i++) | ||
160 | dev->dev_addr[i] = inb(ioaddr + i); | ||
161 | |||
162 | printk(" %pM", dev->dev_addr); | ||
163 | |||
164 | /* Snarf the interrupt now. Someday this could be moved to open(). */ | ||
165 | if (dev->irq < 2) { | ||
166 | static const int irq_16list[] = { 11, 10, 5, 3, 4, 7, 9, 0}; | ||
167 | static const int irq_8list[] = { 7, 5, 3, 4, 9, 0}; | ||
168 | const int *irqp = wordmode ? irq_16list : irq_8list; | ||
169 | do { | ||
170 | int irq = *irqp; | ||
171 | if (request_irq (irq, NULL, 0, "bogus", NULL) != -EBUSY) { | ||
172 | unsigned long cookie = probe_irq_on(); | ||
173 | /* Twinkle the interrupt, and check if it's seen. */ | ||
174 | outb_p(irqmap[irq] | HP_RUN, ioaddr + HP_CONFIGURE); | ||
175 | outb_p( 0x00 | HP_RUN, ioaddr + HP_CONFIGURE); | ||
176 | if (irq == probe_irq_off(cookie) /* It's a good IRQ line! */ | ||
177 | && request_irq (irq, eip_interrupt, 0, DRV_NAME, dev) == 0) { | ||
178 | printk(" selecting IRQ %d.\n", irq); | ||
179 | dev->irq = *irqp; | ||
180 | break; | ||
181 | } | ||
182 | } | ||
183 | } while (*++irqp); | ||
184 | if (*irqp == 0) { | ||
185 | printk(" no free IRQ lines.\n"); | ||
186 | retval = -EBUSY; | ||
187 | goto out; | ||
188 | } | ||
189 | } else { | ||
190 | if (dev->irq == 2) | ||
191 | dev->irq = 9; | ||
192 | if ((retval = request_irq(dev->irq, eip_interrupt, 0, DRV_NAME, dev))) { | ||
193 | printk (" unable to get IRQ %d.\n", dev->irq); | ||
194 | goto out; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | /* Set the base address to point to the NIC, not the "real" base! */ | ||
199 | dev->base_addr = ioaddr + NIC_OFFSET; | ||
200 | dev->netdev_ops = &eip_netdev_ops; | ||
201 | |||
202 | ei_status.name = name; | ||
203 | ei_status.word16 = wordmode; | ||
204 | ei_status.tx_start_page = HP_START_PG; | ||
205 | ei_status.rx_start_page = HP_START_PG + TX_PAGES; | ||
206 | ei_status.stop_page = wordmode ? HP_16BSTOP_PG : HP_8BSTOP_PG; | ||
207 | |||
208 | ei_status.reset_8390 = hp_reset_8390; | ||
209 | ei_status.get_8390_hdr = hp_get_8390_hdr; | ||
210 | ei_status.block_input = hp_block_input; | ||
211 | ei_status.block_output = hp_block_output; | ||
212 | hp_init_card(dev); | ||
213 | |||
214 | retval = register_netdev(dev); | ||
215 | if (retval) | ||
216 | goto out1; | ||
217 | return 0; | ||
218 | out1: | ||
219 | free_irq(dev->irq, dev); | ||
220 | out: | ||
221 | release_region(ioaddr, HP_IO_EXTENT); | ||
222 | return retval; | ||
223 | } | ||
224 | |||
225 | static void | ||
226 | hp_reset_8390(struct net_device *dev) | ||
227 | { | ||
228 | int hp_base = dev->base_addr - NIC_OFFSET; | ||
229 | int saved_config = inb_p(hp_base + HP_CONFIGURE); | ||
230 | |||
231 | if (ei_debug > 1) printk("resetting the 8390 time=%ld...", jiffies); | ||
232 | outb_p(0x00, hp_base + HP_CONFIGURE); | ||
233 | ei_status.txing = 0; | ||
234 | /* Pause just a few cycles for the hardware reset to take place. */ | ||
235 | udelay(5); | ||
236 | |||
237 | outb_p(saved_config, hp_base + HP_CONFIGURE); | ||
238 | udelay(5); | ||
239 | |||
240 | if ((inb_p(hp_base+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0) | ||
241 | printk("%s: hp_reset_8390() did not complete.\n", dev->name); | ||
242 | |||
243 | if (ei_debug > 1) printk("8390 reset done (%ld).", jiffies); | ||
244 | } | ||
245 | |||
246 | static void | ||
247 | hp_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
248 | { | ||
249 | int nic_base = dev->base_addr; | ||
250 | int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE); | ||
251 | |||
252 | outb_p(saved_config | HP_DATAON, nic_base - NIC_OFFSET + HP_CONFIGURE); | ||
253 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base); | ||
254 | outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); | ||
255 | outb_p(0, nic_base + EN0_RCNTHI); | ||
256 | outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ | ||
257 | outb_p(ring_page, nic_base + EN0_RSARHI); | ||
258 | outb_p(E8390_RREAD+E8390_START, nic_base); | ||
259 | |||
260 | if (ei_status.word16) | ||
261 | insw(nic_base - NIC_OFFSET + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1); | ||
262 | else | ||
263 | insb(nic_base - NIC_OFFSET + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)); | ||
264 | |||
265 | outb_p(saved_config & (~HP_DATAON), nic_base - NIC_OFFSET + HP_CONFIGURE); | ||
266 | } | ||
267 | |||
268 | /* Block input and output, similar to the Crynwr packet driver. If you are | ||
269 | porting to a new ethercard look at the packet driver source for hints. | ||
270 | The HP LAN doesn't use shared memory -- we put the packet | ||
271 | out through the "remote DMA" dataport. */ | ||
272 | |||
273 | static void | ||
274 | hp_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
275 | { | ||
276 | int nic_base = dev->base_addr; | ||
277 | int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE); | ||
278 | int xfer_count = count; | ||
279 | char *buf = skb->data; | ||
280 | |||
281 | outb_p(saved_config | HP_DATAON, nic_base - NIC_OFFSET + HP_CONFIGURE); | ||
282 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base); | ||
283 | outb_p(count & 0xff, nic_base + EN0_RCNTLO); | ||
284 | outb_p(count >> 8, nic_base + EN0_RCNTHI); | ||
285 | outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); | ||
286 | outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); | ||
287 | outb_p(E8390_RREAD+E8390_START, nic_base); | ||
288 | if (ei_status.word16) { | ||
289 | insw(nic_base - NIC_OFFSET + HP_DATAPORT,buf,count>>1); | ||
290 | if (count & 0x01) | ||
291 | buf[count-1] = inb(nic_base - NIC_OFFSET + HP_DATAPORT), xfer_count++; | ||
292 | } else { | ||
293 | insb(nic_base - NIC_OFFSET + HP_DATAPORT, buf, count); | ||
294 | } | ||
295 | /* This is for the ALPHA version only, remove for later releases. */ | ||
296 | if (ei_debug > 0) { /* DMA termination address check... */ | ||
297 | int high = inb_p(nic_base + EN0_RSARHI); | ||
298 | int low = inb_p(nic_base + EN0_RSARLO); | ||
299 | int addr = (high << 8) + low; | ||
300 | /* Check only the lower 8 bits so we can ignore ring wrap. */ | ||
301 | if (((ring_offset + xfer_count) & 0xff) != (addr & 0xff)) | ||
302 | printk("%s: RX transfer address mismatch, %#4.4x vs. %#4.4x (actual).\n", | ||
303 | dev->name, ring_offset + xfer_count, addr); | ||
304 | } | ||
305 | outb_p(saved_config & (~HP_DATAON), nic_base - NIC_OFFSET + HP_CONFIGURE); | ||
306 | } | ||
307 | |||
308 | static void | ||
309 | hp_block_output(struct net_device *dev, int count, | ||
310 | const unsigned char *buf, int start_page) | ||
311 | { | ||
312 | int nic_base = dev->base_addr; | ||
313 | int saved_config = inb_p(nic_base - NIC_OFFSET + HP_CONFIGURE); | ||
314 | |||
315 | outb_p(saved_config | HP_DATAON, nic_base - NIC_OFFSET + HP_CONFIGURE); | ||
316 | /* Round the count up for word writes. Do we need to do this? | ||
317 | What effect will an odd byte count have on the 8390? | ||
318 | I should check someday. */ | ||
319 | if (ei_status.word16 && (count & 0x01)) | ||
320 | count++; | ||
321 | /* We should already be in page 0, but to be safe... */ | ||
322 | outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base); | ||
323 | |||
324 | #ifdef NE8390_RW_BUGFIX | ||
325 | /* Handle the read-before-write bug the same way as the | ||
326 | Crynwr packet driver -- the NatSemi method doesn't work. */ | ||
327 | outb_p(0x42, nic_base + EN0_RCNTLO); | ||
328 | outb_p(0, nic_base + EN0_RCNTHI); | ||
329 | outb_p(0xff, nic_base + EN0_RSARLO); | ||
330 | outb_p(0x00, nic_base + EN0_RSARHI); | ||
331 | #define NE_CMD 0x00 | ||
332 | outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
333 | /* Make certain that the dummy read has occurred. */ | ||
334 | inb_p(0x61); | ||
335 | inb_p(0x61); | ||
336 | #endif | ||
337 | |||
338 | outb_p(count & 0xff, nic_base + EN0_RCNTLO); | ||
339 | outb_p(count >> 8, nic_base + EN0_RCNTHI); | ||
340 | outb_p(0x00, nic_base + EN0_RSARLO); | ||
341 | outb_p(start_page, nic_base + EN0_RSARHI); | ||
342 | |||
343 | outb_p(E8390_RWRITE+E8390_START, nic_base); | ||
344 | if (ei_status.word16) { | ||
345 | /* Use the 'rep' sequence for 16 bit boards. */ | ||
346 | outsw(nic_base - NIC_OFFSET + HP_DATAPORT, buf, count>>1); | ||
347 | } else { | ||
348 | outsb(nic_base - NIC_OFFSET + HP_DATAPORT, buf, count); | ||
349 | } | ||
350 | |||
351 | /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here -- it's broken! */ | ||
352 | |||
353 | /* This is for the ALPHA version only, remove for later releases. */ | ||
354 | if (ei_debug > 0) { /* DMA termination address check... */ | ||
355 | int high = inb_p(nic_base + EN0_RSARHI); | ||
356 | int low = inb_p(nic_base + EN0_RSARLO); | ||
357 | int addr = (high << 8) + low; | ||
358 | if ((start_page << 8) + count != addr) | ||
359 | printk("%s: TX Transfer address mismatch, %#4.4x vs. %#4.4x.\n", | ||
360 | dev->name, (start_page << 8) + count, addr); | ||
361 | } | ||
362 | outb_p(saved_config & (~HP_DATAON), nic_base - NIC_OFFSET + HP_CONFIGURE); | ||
363 | } | ||
364 | |||
365 | /* This function resets the ethercard if something screws up. */ | ||
366 | static void __init | ||
367 | hp_init_card(struct net_device *dev) | ||
368 | { | ||
369 | int irq = dev->irq; | ||
370 | NS8390p_init(dev, 0); | ||
371 | outb_p(irqmap[irq&0x0f] | HP_RUN, | ||
372 | dev->base_addr - NIC_OFFSET + HP_CONFIGURE); | ||
373 | } | ||
374 | |||
375 | #ifdef MODULE | ||
376 | #define MAX_HP_CARDS 4 /* Max number of HP cards per module */ | ||
377 | static struct net_device *dev_hp[MAX_HP_CARDS]; | ||
378 | static int io[MAX_HP_CARDS]; | ||
379 | static int irq[MAX_HP_CARDS]; | ||
380 | |||
381 | module_param_array(io, int, NULL, 0); | ||
382 | module_param_array(irq, int, NULL, 0); | ||
383 | MODULE_PARM_DESC(io, "I/O base address(es)"); | ||
384 | MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); | ||
385 | MODULE_DESCRIPTION("HP PC-LAN ISA ethernet driver"); | ||
386 | MODULE_LICENSE("GPL"); | ||
387 | |||
388 | /* This is set up so that only a single autoprobe takes place per call. | ||
389 | ISA device autoprobes on a running machine are not recommended. */ | ||
390 | int __init | ||
391 | init_module(void) | ||
392 | { | ||
393 | struct net_device *dev; | ||
394 | int this_dev, found = 0; | ||
395 | |||
396 | for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) { | ||
397 | if (io[this_dev] == 0) { | ||
398 | if (this_dev != 0) break; /* only autoprobe 1st one */ | ||
399 | printk(KERN_NOTICE "hp.c: Presently autoprobing (not recommended) for a single card.\n"); | ||
400 | } | ||
401 | dev = alloc_eip_netdev(); | ||
402 | if (!dev) | ||
403 | break; | ||
404 | dev->irq = irq[this_dev]; | ||
405 | dev->base_addr = io[this_dev]; | ||
406 | if (do_hp_probe(dev) == 0) { | ||
407 | dev_hp[found++] = dev; | ||
408 | continue; | ||
409 | } | ||
410 | free_netdev(dev); | ||
411 | printk(KERN_WARNING "hp.c: No HP card found (i/o = 0x%x).\n", io[this_dev]); | ||
412 | break; | ||
413 | } | ||
414 | if (found) | ||
415 | return 0; | ||
416 | return -ENXIO; | ||
417 | } | ||
418 | |||
419 | static void cleanup_card(struct net_device *dev) | ||
420 | { | ||
421 | free_irq(dev->irq, dev); | ||
422 | release_region(dev->base_addr - NIC_OFFSET, HP_IO_EXTENT); | ||
423 | } | ||
424 | |||
425 | void __exit | ||
426 | cleanup_module(void) | ||
427 | { | ||
428 | int this_dev; | ||
429 | |||
430 | for (this_dev = 0; this_dev < MAX_HP_CARDS; this_dev++) { | ||
431 | struct net_device *dev = dev_hp[this_dev]; | ||
432 | if (dev) { | ||
433 | unregister_netdev(dev); | ||
434 | cleanup_card(dev); | ||
435 | free_netdev(dev); | ||
436 | } | ||
437 | } | ||
438 | } | ||
439 | #endif /* MODULE */ | ||
diff --git a/drivers/net/ethernet/8390/hydra.c b/drivers/net/ethernet/8390/hydra.c new file mode 100644 index 000000000000..1cd481c04202 --- /dev/null +++ b/drivers/net/ethernet/8390/hydra.c | |||
@@ -0,0 +1,273 @@ | |||
1 | /* New Hydra driver using generic 8390 core */ | ||
2 | /* Based on old hydra driver by Topi Kanerva (topi@susanna.oulu.fi) */ | ||
3 | |||
4 | /* This file is subject to the terms and conditions of the GNU General */ | ||
5 | /* Public License. See the file COPYING in the main directory of the */ | ||
6 | /* Linux distribution for more details. */ | ||
7 | |||
8 | /* Peter De Schrijver (p2@mind.be) */ | ||
9 | /* Oldenburg 2000 */ | ||
10 | |||
11 | /* The Amiganet is a Zorro-II board made by Hydra Systems. It contains a */ | ||
12 | /* NS8390 NIC (network interface controller) clone, 16 or 64K on-board RAM */ | ||
13 | /* and 10BASE-2 (thin coax) and AUI connectors. */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/string.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/ioport.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/netdevice.h> | ||
22 | #include <linux/etherdevice.h> | ||
23 | #include <linux/skbuff.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/bitops.h> | ||
26 | |||
27 | #include <asm/io.h> | ||
28 | #include <asm/irq.h> | ||
29 | #include <asm/amigaints.h> | ||
30 | #include <asm/amigahw.h> | ||
31 | #include <linux/zorro.h> | ||
32 | |||
33 | #define EI_SHIFT(x) (ei_local->reg_offset[x]) | ||
34 | #define ei_inb(port) in_8(port) | ||
35 | #define ei_outb(val,port) out_8(port,val) | ||
36 | #define ei_inb_p(port) in_8(port) | ||
37 | #define ei_outb_p(val,port) out_8(port,val) | ||
38 | |||
39 | static const char version[] = | ||
40 | "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; | ||
41 | |||
42 | #include "lib8390.c" | ||
43 | |||
44 | #define NE_EN0_DCFG (0x0e*2) | ||
45 | |||
46 | #define NESM_START_PG 0x0 /* First page of TX buffer */ | ||
47 | #define NESM_STOP_PG 0x40 /* Last page +1 of RX ring */ | ||
48 | |||
49 | #define HYDRA_NIC_BASE 0xffe1 | ||
50 | #define HYDRA_ADDRPROM 0xffc0 | ||
51 | #define HYDRA_VERSION "v3.0alpha" | ||
52 | |||
53 | #define WORDSWAP(a) ((((a)>>8)&0xff) | ((a)<<8)) | ||
54 | |||
55 | |||
56 | static int __devinit hydra_init_one(struct zorro_dev *z, | ||
57 | const struct zorro_device_id *ent); | ||
58 | static int __devinit hydra_init(struct zorro_dev *z); | ||
59 | static int hydra_open(struct net_device *dev); | ||
60 | static int hydra_close(struct net_device *dev); | ||
61 | static void hydra_reset_8390(struct net_device *dev); | ||
62 | static void hydra_get_8390_hdr(struct net_device *dev, | ||
63 | struct e8390_pkt_hdr *hdr, int ring_page); | ||
64 | static void hydra_block_input(struct net_device *dev, int count, | ||
65 | struct sk_buff *skb, int ring_offset); | ||
66 | static void hydra_block_output(struct net_device *dev, int count, | ||
67 | const unsigned char *buf, int start_page); | ||
68 | static void __devexit hydra_remove_one(struct zorro_dev *z); | ||
69 | |||
70 | static struct zorro_device_id hydra_zorro_tbl[] __devinitdata = { | ||
71 | { ZORRO_PROD_HYDRA_SYSTEMS_AMIGANET }, | ||
72 | { 0 } | ||
73 | }; | ||
74 | MODULE_DEVICE_TABLE(zorro, hydra_zorro_tbl); | ||
75 | |||
76 | static struct zorro_driver hydra_driver = { | ||
77 | .name = "hydra", | ||
78 | .id_table = hydra_zorro_tbl, | ||
79 | .probe = hydra_init_one, | ||
80 | .remove = __devexit_p(hydra_remove_one), | ||
81 | }; | ||
82 | |||
83 | static int __devinit hydra_init_one(struct zorro_dev *z, | ||
84 | const struct zorro_device_id *ent) | ||
85 | { | ||
86 | int err; | ||
87 | |||
88 | if (!request_mem_region(z->resource.start, 0x10000, "Hydra")) | ||
89 | return -EBUSY; | ||
90 | if ((err = hydra_init(z))) { | ||
91 | release_mem_region(z->resource.start, 0x10000); | ||
92 | return -EBUSY; | ||
93 | } | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static const struct net_device_ops hydra_netdev_ops = { | ||
98 | .ndo_open = hydra_open, | ||
99 | .ndo_stop = hydra_close, | ||
100 | |||
101 | .ndo_start_xmit = __ei_start_xmit, | ||
102 | .ndo_tx_timeout = __ei_tx_timeout, | ||
103 | .ndo_get_stats = __ei_get_stats, | ||
104 | .ndo_set_multicast_list = __ei_set_multicast_list, | ||
105 | .ndo_validate_addr = eth_validate_addr, | ||
106 | .ndo_set_mac_address = eth_mac_addr, | ||
107 | .ndo_change_mtu = eth_change_mtu, | ||
108 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
109 | .ndo_poll_controller = __ei_poll, | ||
110 | #endif | ||
111 | }; | ||
112 | |||
113 | static int __devinit hydra_init(struct zorro_dev *z) | ||
114 | { | ||
115 | struct net_device *dev; | ||
116 | unsigned long board = ZTWO_VADDR(z->resource.start); | ||
117 | unsigned long ioaddr = board+HYDRA_NIC_BASE; | ||
118 | const char name[] = "NE2000"; | ||
119 | int start_page, stop_page; | ||
120 | int j; | ||
121 | int err; | ||
122 | |||
123 | static u32 hydra_offsets[16] = { | ||
124 | 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, | ||
125 | 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, | ||
126 | }; | ||
127 | |||
128 | dev = ____alloc_ei_netdev(0); | ||
129 | if (!dev) | ||
130 | return -ENOMEM; | ||
131 | |||
132 | for(j = 0; j < ETHER_ADDR_LEN; j++) | ||
133 | dev->dev_addr[j] = *((u8 *)(board + HYDRA_ADDRPROM + 2*j)); | ||
134 | |||
135 | /* We must set the 8390 for word mode. */ | ||
136 | z_writeb(0x4b, ioaddr + NE_EN0_DCFG); | ||
137 | start_page = NESM_START_PG; | ||
138 | stop_page = NESM_STOP_PG; | ||
139 | |||
140 | dev->base_addr = ioaddr; | ||
141 | dev->irq = IRQ_AMIGA_PORTS; | ||
142 | |||
143 | /* Install the Interrupt handler */ | ||
144 | if (request_irq(IRQ_AMIGA_PORTS, __ei_interrupt, IRQF_SHARED, "Hydra Ethernet", | ||
145 | dev)) { | ||
146 | free_netdev(dev); | ||
147 | return -EAGAIN; | ||
148 | } | ||
149 | |||
150 | ei_status.name = name; | ||
151 | ei_status.tx_start_page = start_page; | ||
152 | ei_status.stop_page = stop_page; | ||
153 | ei_status.word16 = 1; | ||
154 | ei_status.bigendian = 1; | ||
155 | |||
156 | ei_status.rx_start_page = start_page + TX_PAGES; | ||
157 | |||
158 | ei_status.reset_8390 = hydra_reset_8390; | ||
159 | ei_status.block_input = hydra_block_input; | ||
160 | ei_status.block_output = hydra_block_output; | ||
161 | ei_status.get_8390_hdr = hydra_get_8390_hdr; | ||
162 | ei_status.reg_offset = hydra_offsets; | ||
163 | |||
164 | dev->netdev_ops = &hydra_netdev_ops; | ||
165 | __NS8390_init(dev, 0); | ||
166 | |||
167 | err = register_netdev(dev); | ||
168 | if (err) { | ||
169 | free_irq(IRQ_AMIGA_PORTS, dev); | ||
170 | free_netdev(dev); | ||
171 | return err; | ||
172 | } | ||
173 | |||
174 | zorro_set_drvdata(z, dev); | ||
175 | |||
176 | pr_info("%s: Hydra at %pR, address %pM (hydra.c " HYDRA_VERSION ")\n", | ||
177 | dev->name, &z->resource, dev->dev_addr); | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int hydra_open(struct net_device *dev) | ||
183 | { | ||
184 | __ei_open(dev); | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static int hydra_close(struct net_device *dev) | ||
189 | { | ||
190 | if (ei_debug > 1) | ||
191 | printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name); | ||
192 | __ei_close(dev); | ||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static void hydra_reset_8390(struct net_device *dev) | ||
197 | { | ||
198 | printk(KERN_INFO "Hydra hw reset not there\n"); | ||
199 | } | ||
200 | |||
201 | static void hydra_get_8390_hdr(struct net_device *dev, | ||
202 | struct e8390_pkt_hdr *hdr, int ring_page) | ||
203 | { | ||
204 | int nic_base = dev->base_addr; | ||
205 | short *ptrs; | ||
206 | unsigned long hdr_start= (nic_base-HYDRA_NIC_BASE) + | ||
207 | ((ring_page - NESM_START_PG)<<8); | ||
208 | ptrs = (short *)hdr; | ||
209 | |||
210 | *(ptrs++) = z_readw(hdr_start); | ||
211 | *((short *)hdr) = WORDSWAP(*((short *)hdr)); | ||
212 | hdr_start += 2; | ||
213 | *(ptrs++) = z_readw(hdr_start); | ||
214 | *((short *)hdr+1) = WORDSWAP(*((short *)hdr+1)); | ||
215 | } | ||
216 | |||
217 | static void hydra_block_input(struct net_device *dev, int count, | ||
218 | struct sk_buff *skb, int ring_offset) | ||
219 | { | ||
220 | unsigned long nic_base = dev->base_addr; | ||
221 | unsigned long mem_base = nic_base - HYDRA_NIC_BASE; | ||
222 | unsigned long xfer_start = mem_base + ring_offset - (NESM_START_PG<<8); | ||
223 | |||
224 | if (count&1) | ||
225 | count++; | ||
226 | |||
227 | if (xfer_start+count > mem_base + (NESM_STOP_PG<<8)) { | ||
228 | int semi_count = (mem_base + (NESM_STOP_PG<<8)) - xfer_start; | ||
229 | |||
230 | z_memcpy_fromio(skb->data,xfer_start,semi_count); | ||
231 | count -= semi_count; | ||
232 | z_memcpy_fromio(skb->data+semi_count, mem_base, count); | ||
233 | } else | ||
234 | z_memcpy_fromio(skb->data, xfer_start,count); | ||
235 | |||
236 | } | ||
237 | |||
238 | static void hydra_block_output(struct net_device *dev, int count, | ||
239 | const unsigned char *buf, int start_page) | ||
240 | { | ||
241 | unsigned long nic_base = dev->base_addr; | ||
242 | unsigned long mem_base = nic_base - HYDRA_NIC_BASE; | ||
243 | |||
244 | if (count&1) | ||
245 | count++; | ||
246 | |||
247 | z_memcpy_toio(mem_base+((start_page - NESM_START_PG)<<8), buf, count); | ||
248 | } | ||
249 | |||
250 | static void __devexit hydra_remove_one(struct zorro_dev *z) | ||
251 | { | ||
252 | struct net_device *dev = zorro_get_drvdata(z); | ||
253 | |||
254 | unregister_netdev(dev); | ||
255 | free_irq(IRQ_AMIGA_PORTS, dev); | ||
256 | release_mem_region(ZTWO_PADDR(dev->base_addr)-HYDRA_NIC_BASE, 0x10000); | ||
257 | free_netdev(dev); | ||
258 | } | ||
259 | |||
260 | static int __init hydra_init_module(void) | ||
261 | { | ||
262 | return zorro_register_driver(&hydra_driver); | ||
263 | } | ||
264 | |||
265 | static void __exit hydra_cleanup_module(void) | ||
266 | { | ||
267 | zorro_unregister_driver(&hydra_driver); | ||
268 | } | ||
269 | |||
270 | module_init(hydra_init_module); | ||
271 | module_exit(hydra_cleanup_module); | ||
272 | |||
273 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/ethernet/8390/lib8390.c b/drivers/net/ethernet/8390/lib8390.c new file mode 100644 index 000000000000..05ae21435bfd --- /dev/null +++ b/drivers/net/ethernet/8390/lib8390.c | |||
@@ -0,0 +1,1080 @@ | |||
1 | /* 8390.c: A general NS8390 ethernet driver core for linux. */ | ||
2 | /* | ||
3 | Written 1992-94 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 | This is the chip-specific code for many 8390-based ethernet adaptors. | ||
18 | This is not a complete driver, it must be combined with board-specific | ||
19 | code such as ne.c, wd.c, 3c503.c, etc. | ||
20 | |||
21 | Seeing how at least eight drivers use this code, (not counting the | ||
22 | PCMCIA ones either) it is easy to break some card by what seems like | ||
23 | a simple innocent change. Please contact me or Donald if you think | ||
24 | you have found something that needs changing. -- PG | ||
25 | |||
26 | |||
27 | Changelog: | ||
28 | |||
29 | Paul Gortmaker : remove set_bit lock, other cleanups. | ||
30 | Paul Gortmaker : add ei_get_8390_hdr() so we can pass skb's to | ||
31 | ei_block_input() for eth_io_copy_and_sum(). | ||
32 | Paul Gortmaker : exchange static int ei_pingpong for a #define, | ||
33 | also add better Tx error handling. | ||
34 | Paul Gortmaker : rewrite Rx overrun handling as per NS specs. | ||
35 | Alexey Kuznetsov : use the 8390's six bit hash multicast filter. | ||
36 | Paul Gortmaker : tweak ANK's above multicast changes a bit. | ||
37 | Paul Gortmaker : update packet statistics for v2.1.x | ||
38 | Alan Cox : support arbitrary stupid port mappings on the | ||
39 | 68K Macintosh. Support >16bit I/O spaces | ||
40 | Paul Gortmaker : add kmod support for auto-loading of the 8390 | ||
41 | module by all drivers that require it. | ||
42 | Alan Cox : Spinlocking work, added 'BUG_83C690' | ||
43 | Paul Gortmaker : Separate out Tx timeout code from Tx path. | ||
44 | Paul Gortmaker : Remove old unused single Tx buffer code. | ||
45 | Hayato Fujiwara : Add m32r support. | ||
46 | Paul Gortmaker : use skb_padto() instead of stack scratch area | ||
47 | |||
48 | Sources: | ||
49 | The National Semiconductor LAN Databook, and the 3Com 3c503 databook. | ||
50 | |||
51 | */ | ||
52 | |||
53 | #include <linux/module.h> | ||
54 | #include <linux/kernel.h> | ||
55 | #include <linux/jiffies.h> | ||
56 | #include <linux/fs.h> | ||
57 | #include <linux/types.h> | ||
58 | #include <linux/string.h> | ||
59 | #include <linux/bitops.h> | ||
60 | #include <asm/system.h> | ||
61 | #include <linux/uaccess.h> | ||
62 | #include <linux/io.h> | ||
63 | #include <asm/irq.h> | ||
64 | #include <linux/delay.h> | ||
65 | #include <linux/errno.h> | ||
66 | #include <linux/fcntl.h> | ||
67 | #include <linux/in.h> | ||
68 | #include <linux/interrupt.h> | ||
69 | #include <linux/init.h> | ||
70 | #include <linux/crc32.h> | ||
71 | |||
72 | #include <linux/netdevice.h> | ||
73 | #include <linux/etherdevice.h> | ||
74 | |||
75 | #define NS8390_CORE | ||
76 | #include "8390.h" | ||
77 | |||
78 | #define BUG_83C690 | ||
79 | |||
80 | /* These are the operational function interfaces to board-specific | ||
81 | routines. | ||
82 | void reset_8390(struct net_device *dev) | ||
83 | Resets the board associated with DEV, including a hardware reset of | ||
84 | the 8390. This is only called when there is a transmit timeout, and | ||
85 | it is always followed by 8390_init(). | ||
86 | void block_output(struct net_device *dev, int count, const unsigned char *buf, | ||
87 | int start_page) | ||
88 | Write the COUNT bytes of BUF to the packet buffer at START_PAGE. The | ||
89 | "page" value uses the 8390's 256-byte pages. | ||
90 | void get_8390_hdr(struct net_device *dev, struct e8390_hdr *hdr, int ring_page) | ||
91 | Read the 4 byte, page aligned 8390 header. *If* there is a | ||
92 | subsequent read, it will be of the rest of the packet. | ||
93 | void block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
94 | Read COUNT bytes from the packet buffer into the skb data area. Start | ||
95 | reading from RING_OFFSET, the address as the 8390 sees it. This will always | ||
96 | follow the read of the 8390 header. | ||
97 | */ | ||
98 | #define ei_reset_8390 (ei_local->reset_8390) | ||
99 | #define ei_block_output (ei_local->block_output) | ||
100 | #define ei_block_input (ei_local->block_input) | ||
101 | #define ei_get_8390_hdr (ei_local->get_8390_hdr) | ||
102 | |||
103 | /* use 0 for production, 1 for verification, >2 for debug */ | ||
104 | #ifndef ei_debug | ||
105 | int ei_debug = 1; | ||
106 | #endif | ||
107 | |||
108 | /* Index to functions. */ | ||
109 | static void ei_tx_intr(struct net_device *dev); | ||
110 | static void ei_tx_err(struct net_device *dev); | ||
111 | static void ei_receive(struct net_device *dev); | ||
112 | static void ei_rx_overrun(struct net_device *dev); | ||
113 | |||
114 | /* Routines generic to NS8390-based boards. */ | ||
115 | static void NS8390_trigger_send(struct net_device *dev, unsigned int length, | ||
116 | int start_page); | ||
117 | static void do_set_multicast_list(struct net_device *dev); | ||
118 | static void __NS8390_init(struct net_device *dev, int startp); | ||
119 | |||
120 | /* | ||
121 | * SMP and the 8390 setup. | ||
122 | * | ||
123 | * The 8390 isn't exactly designed to be multithreaded on RX/TX. There is | ||
124 | * a page register that controls bank and packet buffer access. We guard | ||
125 | * this with ei_local->page_lock. Nobody should assume or set the page other | ||
126 | * than zero when the lock is not held. Lock holders must restore page 0 | ||
127 | * before unlocking. Even pure readers must take the lock to protect in | ||
128 | * page 0. | ||
129 | * | ||
130 | * To make life difficult the chip can also be very slow. We therefore can't | ||
131 | * just use spinlocks. For the longer lockups we disable the irq the device | ||
132 | * sits on and hold the lock. We must hold the lock because there is a dual | ||
133 | * processor case other than interrupts (get stats/set multicast list in | ||
134 | * parallel with each other and transmit). | ||
135 | * | ||
136 | * Note: in theory we can just disable the irq on the card _but_ there is | ||
137 | * a latency on SMP irq delivery. So we can easily go "disable irq" "sync irqs" | ||
138 | * enter lock, take the queued irq. So we waddle instead of flying. | ||
139 | * | ||
140 | * Finally by special arrangement for the purpose of being generally | ||
141 | * annoying the transmit function is called bh atomic. That places | ||
142 | * restrictions on the user context callers as disable_irq won't save | ||
143 | * them. | ||
144 | * | ||
145 | * Additional explanation of problems with locking by Alan Cox: | ||
146 | * | ||
147 | * "The author (me) didn't use spin_lock_irqsave because the slowness of the | ||
148 | * card means that approach caused horrible problems like losing serial data | ||
149 | * at 38400 baud on some chips. Remember many 8390 nics on PCI were ISA | ||
150 | * chips with FPGA front ends. | ||
151 | * | ||
152 | * Ok the logic behind the 8390 is very simple: | ||
153 | * | ||
154 | * Things to know | ||
155 | * - IRQ delivery is asynchronous to the PCI bus | ||
156 | * - Blocking the local CPU IRQ via spin locks was too slow | ||
157 | * - The chip has register windows needing locking work | ||
158 | * | ||
159 | * So the path was once (I say once as people appear to have changed it | ||
160 | * in the mean time and it now looks rather bogus if the changes to use | ||
161 | * disable_irq_nosync_irqsave are disabling the local IRQ) | ||
162 | * | ||
163 | * | ||
164 | * Take the page lock | ||
165 | * Mask the IRQ on chip | ||
166 | * Disable the IRQ (but not mask locally- someone seems to have | ||
167 | * broken this with the lock validator stuff) | ||
168 | * [This must be _nosync as the page lock may otherwise | ||
169 | * deadlock us] | ||
170 | * Drop the page lock and turn IRQs back on | ||
171 | * | ||
172 | * At this point an existing IRQ may still be running but we can't | ||
173 | * get a new one | ||
174 | * | ||
175 | * Take the lock (so we know the IRQ has terminated) but don't mask | ||
176 | * the IRQs on the processor | ||
177 | * Set irqlock [for debug] | ||
178 | * | ||
179 | * Transmit (slow as ****) | ||
180 | * | ||
181 | * re-enable the IRQ | ||
182 | * | ||
183 | * | ||
184 | * We have to use disable_irq because otherwise you will get delayed | ||
185 | * interrupts on the APIC bus deadlocking the transmit path. | ||
186 | * | ||
187 | * Quite hairy but the chip simply wasn't designed for SMP and you can't | ||
188 | * even ACK an interrupt without risking corrupting other parallel | ||
189 | * activities on the chip." [lkml, 25 Jul 2007] | ||
190 | */ | ||
191 | |||
192 | |||
193 | |||
194 | /** | ||
195 | * ei_open - Open/initialize the board. | ||
196 | * @dev: network device to initialize | ||
197 | * | ||
198 | * This routine goes all-out, setting everything | ||
199 | * up anew at each open, even though many of these registers should only | ||
200 | * need to be set once at boot. | ||
201 | */ | ||
202 | static int __ei_open(struct net_device *dev) | ||
203 | { | ||
204 | unsigned long flags; | ||
205 | struct ei_device *ei_local = netdev_priv(dev); | ||
206 | |||
207 | if (dev->watchdog_timeo <= 0) | ||
208 | dev->watchdog_timeo = TX_TIMEOUT; | ||
209 | |||
210 | /* | ||
211 | * Grab the page lock so we own the register set, then call | ||
212 | * the init function. | ||
213 | */ | ||
214 | |||
215 | spin_lock_irqsave(&ei_local->page_lock, flags); | ||
216 | __NS8390_init(dev, 1); | ||
217 | /* Set the flag before we drop the lock, That way the IRQ arrives | ||
218 | after its set and we get no silly warnings */ | ||
219 | netif_start_queue(dev); | ||
220 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
221 | ei_local->irqlock = 0; | ||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * ei_close - shut down network device | ||
227 | * @dev: network device to close | ||
228 | * | ||
229 | * Opposite of ei_open(). Only used when "ifconfig <devname> down" is done. | ||
230 | */ | ||
231 | static int __ei_close(struct net_device *dev) | ||
232 | { | ||
233 | struct ei_device *ei_local = netdev_priv(dev); | ||
234 | unsigned long flags; | ||
235 | |||
236 | /* | ||
237 | * Hold the page lock during close | ||
238 | */ | ||
239 | |||
240 | spin_lock_irqsave(&ei_local->page_lock, flags); | ||
241 | __NS8390_init(dev, 0); | ||
242 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
243 | netif_stop_queue(dev); | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | /** | ||
248 | * ei_tx_timeout - handle transmit time out condition | ||
249 | * @dev: network device which has apparently fallen asleep | ||
250 | * | ||
251 | * Called by kernel when device never acknowledges a transmit has | ||
252 | * completed (or failed) - i.e. never posted a Tx related interrupt. | ||
253 | */ | ||
254 | |||
255 | static void __ei_tx_timeout(struct net_device *dev) | ||
256 | { | ||
257 | unsigned long e8390_base = dev->base_addr; | ||
258 | struct ei_device *ei_local = netdev_priv(dev); | ||
259 | int txsr, isr, tickssofar = jiffies - dev_trans_start(dev); | ||
260 | unsigned long flags; | ||
261 | |||
262 | dev->stats.tx_errors++; | ||
263 | |||
264 | spin_lock_irqsave(&ei_local->page_lock, flags); | ||
265 | txsr = ei_inb(e8390_base+EN0_TSR); | ||
266 | isr = ei_inb(e8390_base+EN0_ISR); | ||
267 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
268 | |||
269 | netdev_dbg(dev, "Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d\n", | ||
270 | (txsr & ENTSR_ABT) ? "excess collisions." : | ||
271 | (isr) ? "lost interrupt?" : "cable problem?", | ||
272 | txsr, isr, tickssofar); | ||
273 | |||
274 | if (!isr && !dev->stats.tx_packets) { | ||
275 | /* The 8390 probably hasn't gotten on the cable yet. */ | ||
276 | ei_local->interface_num ^= 1; /* Try a different xcvr. */ | ||
277 | } | ||
278 | |||
279 | /* Ugly but a reset can be slow, yet must be protected */ | ||
280 | |||
281 | disable_irq_nosync_lockdep(dev->irq); | ||
282 | spin_lock(&ei_local->page_lock); | ||
283 | |||
284 | /* Try to restart the card. Perhaps the user has fixed something. */ | ||
285 | ei_reset_8390(dev); | ||
286 | __NS8390_init(dev, 1); | ||
287 | |||
288 | spin_unlock(&ei_local->page_lock); | ||
289 | enable_irq_lockdep(dev->irq); | ||
290 | netif_wake_queue(dev); | ||
291 | } | ||
292 | |||
293 | /** | ||
294 | * ei_start_xmit - begin packet transmission | ||
295 | * @skb: packet to be sent | ||
296 | * @dev: network device to which packet is sent | ||
297 | * | ||
298 | * Sends a packet to an 8390 network device. | ||
299 | */ | ||
300 | |||
301 | static netdev_tx_t __ei_start_xmit(struct sk_buff *skb, | ||
302 | struct net_device *dev) | ||
303 | { | ||
304 | unsigned long e8390_base = dev->base_addr; | ||
305 | struct ei_device *ei_local = netdev_priv(dev); | ||
306 | int send_length = skb->len, output_page; | ||
307 | unsigned long flags; | ||
308 | char buf[ETH_ZLEN]; | ||
309 | char *data = skb->data; | ||
310 | |||
311 | if (skb->len < ETH_ZLEN) { | ||
312 | memset(buf, 0, ETH_ZLEN); /* more efficient than doing just the needed bits */ | ||
313 | memcpy(buf, data, skb->len); | ||
314 | send_length = ETH_ZLEN; | ||
315 | data = buf; | ||
316 | } | ||
317 | |||
318 | /* Mask interrupts from the ethercard. | ||
319 | SMP: We have to grab the lock here otherwise the IRQ handler | ||
320 | on another CPU can flip window and race the IRQ mask set. We end | ||
321 | up trashing the mcast filter not disabling irqs if we don't lock */ | ||
322 | |||
323 | spin_lock_irqsave(&ei_local->page_lock, flags); | ||
324 | ei_outb_p(0x00, e8390_base + EN0_IMR); | ||
325 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
326 | |||
327 | |||
328 | /* | ||
329 | * Slow phase with lock held. | ||
330 | */ | ||
331 | |||
332 | disable_irq_nosync_lockdep_irqsave(dev->irq, &flags); | ||
333 | |||
334 | spin_lock(&ei_local->page_lock); | ||
335 | |||
336 | ei_local->irqlock = 1; | ||
337 | |||
338 | /* | ||
339 | * We have two Tx slots available for use. Find the first free | ||
340 | * slot, and then perform some sanity checks. With two Tx bufs, | ||
341 | * you get very close to transmitting back-to-back packets. With | ||
342 | * only one Tx buf, the transmitter sits idle while you reload the | ||
343 | * card, leaving a substantial gap between each transmitted packet. | ||
344 | */ | ||
345 | |||
346 | if (ei_local->tx1 == 0) { | ||
347 | output_page = ei_local->tx_start_page; | ||
348 | ei_local->tx1 = send_length; | ||
349 | if (ei_debug && ei_local->tx2 > 0) | ||
350 | netdev_dbg(dev, "idle transmitter tx2=%d, lasttx=%d, txing=%d\n", | ||
351 | ei_local->tx2, ei_local->lasttx, ei_local->txing); | ||
352 | } else if (ei_local->tx2 == 0) { | ||
353 | output_page = ei_local->tx_start_page + TX_PAGES/2; | ||
354 | ei_local->tx2 = send_length; | ||
355 | if (ei_debug && ei_local->tx1 > 0) | ||
356 | netdev_dbg(dev, "idle transmitter, tx1=%d, lasttx=%d, txing=%d\n", | ||
357 | ei_local->tx1, ei_local->lasttx, ei_local->txing); | ||
358 | } else { /* We should never get here. */ | ||
359 | if (ei_debug) | ||
360 | netdev_dbg(dev, "No Tx buffers free! tx1=%d tx2=%d last=%d\n", | ||
361 | ei_local->tx1, ei_local->tx2, ei_local->lasttx); | ||
362 | ei_local->irqlock = 0; | ||
363 | netif_stop_queue(dev); | ||
364 | ei_outb_p(ENISR_ALL, e8390_base + EN0_IMR); | ||
365 | spin_unlock(&ei_local->page_lock); | ||
366 | enable_irq_lockdep_irqrestore(dev->irq, &flags); | ||
367 | dev->stats.tx_errors++; | ||
368 | return NETDEV_TX_BUSY; | ||
369 | } | ||
370 | |||
371 | /* | ||
372 | * Okay, now upload the packet and trigger a send if the transmitter | ||
373 | * isn't already sending. If it is busy, the interrupt handler will | ||
374 | * trigger the send later, upon receiving a Tx done interrupt. | ||
375 | */ | ||
376 | |||
377 | ei_block_output(dev, send_length, data, output_page); | ||
378 | |||
379 | if (!ei_local->txing) { | ||
380 | ei_local->txing = 1; | ||
381 | NS8390_trigger_send(dev, send_length, output_page); | ||
382 | if (output_page == ei_local->tx_start_page) { | ||
383 | ei_local->tx1 = -1; | ||
384 | ei_local->lasttx = -1; | ||
385 | } else { | ||
386 | ei_local->tx2 = -1; | ||
387 | ei_local->lasttx = -2; | ||
388 | } | ||
389 | } else | ||
390 | ei_local->txqueue++; | ||
391 | |||
392 | if (ei_local->tx1 && ei_local->tx2) | ||
393 | netif_stop_queue(dev); | ||
394 | else | ||
395 | netif_start_queue(dev); | ||
396 | |||
397 | /* Turn 8390 interrupts back on. */ | ||
398 | ei_local->irqlock = 0; | ||
399 | ei_outb_p(ENISR_ALL, e8390_base + EN0_IMR); | ||
400 | |||
401 | spin_unlock(&ei_local->page_lock); | ||
402 | enable_irq_lockdep_irqrestore(dev->irq, &flags); | ||
403 | skb_tx_timestamp(skb); | ||
404 | dev_kfree_skb(skb); | ||
405 | dev->stats.tx_bytes += send_length; | ||
406 | |||
407 | return NETDEV_TX_OK; | ||
408 | } | ||
409 | |||
410 | /** | ||
411 | * ei_interrupt - handle the interrupts from an 8390 | ||
412 | * @irq: interrupt number | ||
413 | * @dev_id: a pointer to the net_device | ||
414 | * | ||
415 | * Handle the ether interface interrupts. We pull packets from | ||
416 | * the 8390 via the card specific functions and fire them at the networking | ||
417 | * stack. We also handle transmit completions and wake the transmit path if | ||
418 | * necessary. We also update the counters and do other housekeeping as | ||
419 | * needed. | ||
420 | */ | ||
421 | |||
422 | static irqreturn_t __ei_interrupt(int irq, void *dev_id) | ||
423 | { | ||
424 | struct net_device *dev = dev_id; | ||
425 | unsigned long e8390_base = dev->base_addr; | ||
426 | int interrupts, nr_serviced = 0; | ||
427 | struct ei_device *ei_local = netdev_priv(dev); | ||
428 | |||
429 | /* | ||
430 | * Protect the irq test too. | ||
431 | */ | ||
432 | |||
433 | spin_lock(&ei_local->page_lock); | ||
434 | |||
435 | if (ei_local->irqlock) { | ||
436 | /* | ||
437 | * This might just be an interrupt for a PCI device sharing | ||
438 | * this line | ||
439 | */ | ||
440 | netdev_err(dev, "Interrupted while interrupts are masked! isr=%#2x imr=%#2x\n", | ||
441 | ei_inb_p(e8390_base + EN0_ISR), | ||
442 | ei_inb_p(e8390_base + EN0_IMR)); | ||
443 | spin_unlock(&ei_local->page_lock); | ||
444 | return IRQ_NONE; | ||
445 | } | ||
446 | |||
447 | /* Change to page 0 and read the intr status reg. */ | ||
448 | ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD); | ||
449 | if (ei_debug > 3) | ||
450 | netdev_dbg(dev, "interrupt(isr=%#2.2x)\n", | ||
451 | ei_inb_p(e8390_base + EN0_ISR)); | ||
452 | |||
453 | /* !!Assumption!! -- we stay in page 0. Don't break this. */ | ||
454 | while ((interrupts = ei_inb_p(e8390_base + EN0_ISR)) != 0 && | ||
455 | ++nr_serviced < MAX_SERVICE) { | ||
456 | if (!netif_running(dev)) { | ||
457 | netdev_warn(dev, "interrupt from stopped card\n"); | ||
458 | /* rmk - acknowledge the interrupts */ | ||
459 | ei_outb_p(interrupts, e8390_base + EN0_ISR); | ||
460 | interrupts = 0; | ||
461 | break; | ||
462 | } | ||
463 | if (interrupts & ENISR_OVER) | ||
464 | ei_rx_overrun(dev); | ||
465 | else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) { | ||
466 | /* Got a good (?) packet. */ | ||
467 | ei_receive(dev); | ||
468 | } | ||
469 | /* Push the next to-transmit packet through. */ | ||
470 | if (interrupts & ENISR_TX) | ||
471 | ei_tx_intr(dev); | ||
472 | else if (interrupts & ENISR_TX_ERR) | ||
473 | ei_tx_err(dev); | ||
474 | |||
475 | if (interrupts & ENISR_COUNTERS) { | ||
476 | dev->stats.rx_frame_errors += ei_inb_p(e8390_base + EN0_COUNTER0); | ||
477 | dev->stats.rx_crc_errors += ei_inb_p(e8390_base + EN0_COUNTER1); | ||
478 | dev->stats.rx_missed_errors += ei_inb_p(e8390_base + EN0_COUNTER2); | ||
479 | ei_outb_p(ENISR_COUNTERS, e8390_base + EN0_ISR); /* Ack intr. */ | ||
480 | } | ||
481 | |||
482 | /* Ignore any RDC interrupts that make it back to here. */ | ||
483 | if (interrupts & ENISR_RDC) | ||
484 | ei_outb_p(ENISR_RDC, e8390_base + EN0_ISR); | ||
485 | |||
486 | ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD); | ||
487 | } | ||
488 | |||
489 | if (interrupts && ei_debug) { | ||
490 | ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD); | ||
491 | if (nr_serviced >= MAX_SERVICE) { | ||
492 | /* 0xFF is valid for a card removal */ | ||
493 | if (interrupts != 0xFF) | ||
494 | netdev_warn(dev, "Too much work at interrupt, status %#2.2x\n", | ||
495 | interrupts); | ||
496 | ei_outb_p(ENISR_ALL, e8390_base + EN0_ISR); /* Ack. most intrs. */ | ||
497 | } else { | ||
498 | netdev_warn(dev, "unknown interrupt %#2x\n", interrupts); | ||
499 | ei_outb_p(0xff, e8390_base + EN0_ISR); /* Ack. all intrs. */ | ||
500 | } | ||
501 | } | ||
502 | spin_unlock(&ei_local->page_lock); | ||
503 | return IRQ_RETVAL(nr_serviced > 0); | ||
504 | } | ||
505 | |||
506 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
507 | static void __ei_poll(struct net_device *dev) | ||
508 | { | ||
509 | disable_irq(dev->irq); | ||
510 | __ei_interrupt(dev->irq, dev); | ||
511 | enable_irq(dev->irq); | ||
512 | } | ||
513 | #endif | ||
514 | |||
515 | /** | ||
516 | * ei_tx_err - handle transmitter error | ||
517 | * @dev: network device which threw the exception | ||
518 | * | ||
519 | * A transmitter error has happened. Most likely excess collisions (which | ||
520 | * is a fairly normal condition). If the error is one where the Tx will | ||
521 | * have been aborted, we try and send another one right away, instead of | ||
522 | * letting the failed packet sit and collect dust in the Tx buffer. This | ||
523 | * is a much better solution as it avoids kernel based Tx timeouts, and | ||
524 | * an unnecessary card reset. | ||
525 | * | ||
526 | * Called with lock held. | ||
527 | */ | ||
528 | |||
529 | static void ei_tx_err(struct net_device *dev) | ||
530 | { | ||
531 | unsigned long e8390_base = dev->base_addr; | ||
532 | /* ei_local is used on some platforms via the EI_SHIFT macro */ | ||
533 | struct ei_device *ei_local __maybe_unused = netdev_priv(dev); | ||
534 | unsigned char txsr = ei_inb_p(e8390_base+EN0_TSR); | ||
535 | unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU); | ||
536 | |||
537 | #ifdef VERBOSE_ERROR_DUMP | ||
538 | netdev_dbg(dev, "transmitter error (%#2x):", txsr); | ||
539 | if (txsr & ENTSR_ABT) | ||
540 | pr_cont(" excess-collisions "); | ||
541 | if (txsr & ENTSR_ND) | ||
542 | pr_cont(" non-deferral "); | ||
543 | if (txsr & ENTSR_CRS) | ||
544 | pr_cont(" lost-carrier "); | ||
545 | if (txsr & ENTSR_FU) | ||
546 | pr_cont(" FIFO-underrun "); | ||
547 | if (txsr & ENTSR_CDH) | ||
548 | pr_cont(" lost-heartbeat "); | ||
549 | pr_cont("\n"); | ||
550 | #endif | ||
551 | |||
552 | ei_outb_p(ENISR_TX_ERR, e8390_base + EN0_ISR); /* Ack intr. */ | ||
553 | |||
554 | if (tx_was_aborted) | ||
555 | ei_tx_intr(dev); | ||
556 | else { | ||
557 | dev->stats.tx_errors++; | ||
558 | if (txsr & ENTSR_CRS) | ||
559 | dev->stats.tx_carrier_errors++; | ||
560 | if (txsr & ENTSR_CDH) | ||
561 | dev->stats.tx_heartbeat_errors++; | ||
562 | if (txsr & ENTSR_OWC) | ||
563 | dev->stats.tx_window_errors++; | ||
564 | } | ||
565 | } | ||
566 | |||
567 | /** | ||
568 | * ei_tx_intr - transmit interrupt handler | ||
569 | * @dev: network device for which tx intr is handled | ||
570 | * | ||
571 | * We have finished a transmit: check for errors and then trigger the next | ||
572 | * packet to be sent. Called with lock held. | ||
573 | */ | ||
574 | |||
575 | static void ei_tx_intr(struct net_device *dev) | ||
576 | { | ||
577 | unsigned long e8390_base = dev->base_addr; | ||
578 | struct ei_device *ei_local = netdev_priv(dev); | ||
579 | int status = ei_inb(e8390_base + EN0_TSR); | ||
580 | |||
581 | ei_outb_p(ENISR_TX, e8390_base + EN0_ISR); /* Ack intr. */ | ||
582 | |||
583 | /* | ||
584 | * There are two Tx buffers, see which one finished, and trigger | ||
585 | * the send of another one if it exists. | ||
586 | */ | ||
587 | ei_local->txqueue--; | ||
588 | |||
589 | if (ei_local->tx1 < 0) { | ||
590 | if (ei_local->lasttx != 1 && ei_local->lasttx != -1) | ||
591 | pr_err("%s: bogus last_tx_buffer %d, tx1=%d\n", | ||
592 | ei_local->name, ei_local->lasttx, ei_local->tx1); | ||
593 | ei_local->tx1 = 0; | ||
594 | if (ei_local->tx2 > 0) { | ||
595 | ei_local->txing = 1; | ||
596 | NS8390_trigger_send(dev, ei_local->tx2, ei_local->tx_start_page + 6); | ||
597 | dev->trans_start = jiffies; | ||
598 | ei_local->tx2 = -1, | ||
599 | ei_local->lasttx = 2; | ||
600 | } else | ||
601 | ei_local->lasttx = 20, ei_local->txing = 0; | ||
602 | } else if (ei_local->tx2 < 0) { | ||
603 | if (ei_local->lasttx != 2 && ei_local->lasttx != -2) | ||
604 | pr_err("%s: bogus last_tx_buffer %d, tx2=%d\n", | ||
605 | ei_local->name, ei_local->lasttx, ei_local->tx2); | ||
606 | ei_local->tx2 = 0; | ||
607 | if (ei_local->tx1 > 0) { | ||
608 | ei_local->txing = 1; | ||
609 | NS8390_trigger_send(dev, ei_local->tx1, ei_local->tx_start_page); | ||
610 | dev->trans_start = jiffies; | ||
611 | ei_local->tx1 = -1; | ||
612 | ei_local->lasttx = 1; | ||
613 | } else | ||
614 | ei_local->lasttx = 10, ei_local->txing = 0; | ||
615 | } /* else | ||
616 | netdev_warn(dev, "unexpected TX-done interrupt, lasttx=%d\n", | ||
617 | ei_local->lasttx); | ||
618 | */ | ||
619 | |||
620 | /* Minimize Tx latency: update the statistics after we restart TXing. */ | ||
621 | if (status & ENTSR_COL) | ||
622 | dev->stats.collisions++; | ||
623 | if (status & ENTSR_PTX) | ||
624 | dev->stats.tx_packets++; | ||
625 | else { | ||
626 | dev->stats.tx_errors++; | ||
627 | if (status & ENTSR_ABT) { | ||
628 | dev->stats.tx_aborted_errors++; | ||
629 | dev->stats.collisions += 16; | ||
630 | } | ||
631 | if (status & ENTSR_CRS) | ||
632 | dev->stats.tx_carrier_errors++; | ||
633 | if (status & ENTSR_FU) | ||
634 | dev->stats.tx_fifo_errors++; | ||
635 | if (status & ENTSR_CDH) | ||
636 | dev->stats.tx_heartbeat_errors++; | ||
637 | if (status & ENTSR_OWC) | ||
638 | dev->stats.tx_window_errors++; | ||
639 | } | ||
640 | netif_wake_queue(dev); | ||
641 | } | ||
642 | |||
643 | /** | ||
644 | * ei_receive - receive some packets | ||
645 | * @dev: network device with which receive will be run | ||
646 | * | ||
647 | * We have a good packet(s), get it/them out of the buffers. | ||
648 | * Called with lock held. | ||
649 | */ | ||
650 | |||
651 | static void ei_receive(struct net_device *dev) | ||
652 | { | ||
653 | unsigned long e8390_base = dev->base_addr; | ||
654 | struct ei_device *ei_local = netdev_priv(dev); | ||
655 | unsigned char rxing_page, this_frame, next_frame; | ||
656 | unsigned short current_offset; | ||
657 | int rx_pkt_count = 0; | ||
658 | struct e8390_pkt_hdr rx_frame; | ||
659 | int num_rx_pages = ei_local->stop_page-ei_local->rx_start_page; | ||
660 | |||
661 | while (++rx_pkt_count < 10) { | ||
662 | int pkt_len, pkt_stat; | ||
663 | |||
664 | /* Get the rx page (incoming packet pointer). */ | ||
665 | ei_outb_p(E8390_NODMA+E8390_PAGE1, e8390_base + E8390_CMD); | ||
666 | rxing_page = ei_inb_p(e8390_base + EN1_CURPAG); | ||
667 | ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD); | ||
668 | |||
669 | /* Remove one frame from the ring. Boundary is always a page behind. */ | ||
670 | this_frame = ei_inb_p(e8390_base + EN0_BOUNDARY) + 1; | ||
671 | if (this_frame >= ei_local->stop_page) | ||
672 | this_frame = ei_local->rx_start_page; | ||
673 | |||
674 | /* Someday we'll omit the previous, iff we never get this message. | ||
675 | (There is at least one clone claimed to have a problem.) | ||
676 | |||
677 | Keep quiet if it looks like a card removal. One problem here | ||
678 | is that some clones crash in roughly the same way. | ||
679 | */ | ||
680 | if (ei_debug > 0 && | ||
681 | this_frame != ei_local->current_page && | ||
682 | (this_frame != 0x0 || rxing_page != 0xFF)) | ||
683 | netdev_err(dev, "mismatched read page pointers %2x vs %2x\n", | ||
684 | this_frame, ei_local->current_page); | ||
685 | |||
686 | if (this_frame == rxing_page) /* Read all the frames? */ | ||
687 | break; /* Done for now */ | ||
688 | |||
689 | current_offset = this_frame << 8; | ||
690 | ei_get_8390_hdr(dev, &rx_frame, this_frame); | ||
691 | |||
692 | pkt_len = rx_frame.count - sizeof(struct e8390_pkt_hdr); | ||
693 | pkt_stat = rx_frame.status; | ||
694 | |||
695 | next_frame = this_frame + 1 + ((pkt_len+4)>>8); | ||
696 | |||
697 | /* Check for bogosity warned by 3c503 book: the status byte is never | ||
698 | written. This happened a lot during testing! This code should be | ||
699 | cleaned up someday. */ | ||
700 | if (rx_frame.next != next_frame && | ||
701 | rx_frame.next != next_frame + 1 && | ||
702 | rx_frame.next != next_frame - num_rx_pages && | ||
703 | rx_frame.next != next_frame + 1 - num_rx_pages) { | ||
704 | ei_local->current_page = rxing_page; | ||
705 | ei_outb(ei_local->current_page-1, e8390_base+EN0_BOUNDARY); | ||
706 | dev->stats.rx_errors++; | ||
707 | continue; | ||
708 | } | ||
709 | |||
710 | if (pkt_len < 60 || pkt_len > 1518) { | ||
711 | if (ei_debug) | ||
712 | netdev_dbg(dev, "bogus packet size: %d, status=%#2x nxpg=%#2x\n", | ||
713 | rx_frame.count, rx_frame.status, | ||
714 | rx_frame.next); | ||
715 | dev->stats.rx_errors++; | ||
716 | dev->stats.rx_length_errors++; | ||
717 | } else if ((pkt_stat & 0x0F) == ENRSR_RXOK) { | ||
718 | struct sk_buff *skb; | ||
719 | |||
720 | skb = dev_alloc_skb(pkt_len+2); | ||
721 | if (skb == NULL) { | ||
722 | if (ei_debug > 1) | ||
723 | netdev_dbg(dev, "Couldn't allocate a sk_buff of size %d\n", | ||
724 | pkt_len); | ||
725 | dev->stats.rx_dropped++; | ||
726 | break; | ||
727 | } else { | ||
728 | skb_reserve(skb, 2); /* IP headers on 16 byte boundaries */ | ||
729 | skb_put(skb, pkt_len); /* Make room */ | ||
730 | ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame)); | ||
731 | skb->protocol = eth_type_trans(skb, dev); | ||
732 | if (!skb_defer_rx_timestamp(skb)) | ||
733 | netif_rx(skb); | ||
734 | dev->stats.rx_packets++; | ||
735 | dev->stats.rx_bytes += pkt_len; | ||
736 | if (pkt_stat & ENRSR_PHY) | ||
737 | dev->stats.multicast++; | ||
738 | } | ||
739 | } else { | ||
740 | if (ei_debug) | ||
741 | netdev_dbg(dev, "bogus packet: status=%#2x nxpg=%#2x size=%d\n", | ||
742 | rx_frame.status, rx_frame.next, | ||
743 | rx_frame.count); | ||
744 | dev->stats.rx_errors++; | ||
745 | /* NB: The NIC counts CRC, frame and missed errors. */ | ||
746 | if (pkt_stat & ENRSR_FO) | ||
747 | dev->stats.rx_fifo_errors++; | ||
748 | } | ||
749 | next_frame = rx_frame.next; | ||
750 | |||
751 | /* This _should_ never happen: it's here for avoiding bad clones. */ | ||
752 | if (next_frame >= ei_local->stop_page) { | ||
753 | netdev_notice(dev, "next frame inconsistency, %#2x\n", | ||
754 | next_frame); | ||
755 | next_frame = ei_local->rx_start_page; | ||
756 | } | ||
757 | ei_local->current_page = next_frame; | ||
758 | ei_outb_p(next_frame-1, e8390_base+EN0_BOUNDARY); | ||
759 | } | ||
760 | |||
761 | /* We used to also ack ENISR_OVER here, but that would sometimes mask | ||
762 | a real overrun, leaving the 8390 in a stopped state with rec'vr off. */ | ||
763 | ei_outb_p(ENISR_RX+ENISR_RX_ERR, e8390_base+EN0_ISR); | ||
764 | } | ||
765 | |||
766 | /** | ||
767 | * ei_rx_overrun - handle receiver overrun | ||
768 | * @dev: network device which threw exception | ||
769 | * | ||
770 | * We have a receiver overrun: we have to kick the 8390 to get it started | ||
771 | * again. Problem is that you have to kick it exactly as NS prescribes in | ||
772 | * the updated datasheets, or "the NIC may act in an unpredictable manner." | ||
773 | * This includes causing "the NIC to defer indefinitely when it is stopped | ||
774 | * on a busy network." Ugh. | ||
775 | * Called with lock held. Don't call this with the interrupts off or your | ||
776 | * computer will hate you - it takes 10ms or so. | ||
777 | */ | ||
778 | |||
779 | static void ei_rx_overrun(struct net_device *dev) | ||
780 | { | ||
781 | unsigned long e8390_base = dev->base_addr; | ||
782 | unsigned char was_txing, must_resend = 0; | ||
783 | /* ei_local is used on some platforms via the EI_SHIFT macro */ | ||
784 | struct ei_device *ei_local __maybe_unused = netdev_priv(dev); | ||
785 | |||
786 | /* | ||
787 | * Record whether a Tx was in progress and then issue the | ||
788 | * stop command. | ||
789 | */ | ||
790 | was_txing = ei_inb_p(e8390_base+E8390_CMD) & E8390_TRANS; | ||
791 | ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); | ||
792 | |||
793 | if (ei_debug > 1) | ||
794 | netdev_dbg(dev, "Receiver overrun\n"); | ||
795 | dev->stats.rx_over_errors++; | ||
796 | |||
797 | /* | ||
798 | * Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total. | ||
799 | * Early datasheets said to poll the reset bit, but now they say that | ||
800 | * it "is not a reliable indicator and subsequently should be ignored." | ||
801 | * We wait at least 10ms. | ||
802 | */ | ||
803 | |||
804 | mdelay(10); | ||
805 | |||
806 | /* | ||
807 | * Reset RBCR[01] back to zero as per magic incantation. | ||
808 | */ | ||
809 | ei_outb_p(0x00, e8390_base+EN0_RCNTLO); | ||
810 | ei_outb_p(0x00, e8390_base+EN0_RCNTHI); | ||
811 | |||
812 | /* | ||
813 | * See if any Tx was interrupted or not. According to NS, this | ||
814 | * step is vital, and skipping it will cause no end of havoc. | ||
815 | */ | ||
816 | |||
817 | if (was_txing) { | ||
818 | unsigned char tx_completed = ei_inb_p(e8390_base+EN0_ISR) & (ENISR_TX+ENISR_TX_ERR); | ||
819 | if (!tx_completed) | ||
820 | must_resend = 1; | ||
821 | } | ||
822 | |||
823 | /* | ||
824 | * Have to enter loopback mode and then restart the NIC before | ||
825 | * you are allowed to slurp packets up off the ring. | ||
826 | */ | ||
827 | ei_outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); | ||
828 | ei_outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, e8390_base + E8390_CMD); | ||
829 | |||
830 | /* | ||
831 | * Clear the Rx ring of all the debris, and ack the interrupt. | ||
832 | */ | ||
833 | ei_receive(dev); | ||
834 | ei_outb_p(ENISR_OVER, e8390_base+EN0_ISR); | ||
835 | |||
836 | /* | ||
837 | * Leave loopback mode, and resend any packet that got stopped. | ||
838 | */ | ||
839 | ei_outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); | ||
840 | if (must_resend) | ||
841 | ei_outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, e8390_base + E8390_CMD); | ||
842 | } | ||
843 | |||
844 | /* | ||
845 | * Collect the stats. This is called unlocked and from several contexts. | ||
846 | */ | ||
847 | |||
848 | static struct net_device_stats *__ei_get_stats(struct net_device *dev) | ||
849 | { | ||
850 | unsigned long ioaddr = dev->base_addr; | ||
851 | struct ei_device *ei_local = netdev_priv(dev); | ||
852 | unsigned long flags; | ||
853 | |||
854 | /* If the card is stopped, just return the present stats. */ | ||
855 | if (!netif_running(dev)) | ||
856 | return &dev->stats; | ||
857 | |||
858 | spin_lock_irqsave(&ei_local->page_lock, flags); | ||
859 | /* Read the counter registers, assuming we are in page 0. */ | ||
860 | dev->stats.rx_frame_errors += ei_inb_p(ioaddr + EN0_COUNTER0); | ||
861 | dev->stats.rx_crc_errors += ei_inb_p(ioaddr + EN0_COUNTER1); | ||
862 | dev->stats.rx_missed_errors += ei_inb_p(ioaddr + EN0_COUNTER2); | ||
863 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
864 | |||
865 | return &dev->stats; | ||
866 | } | ||
867 | |||
868 | /* | ||
869 | * Form the 64 bit 8390 multicast table from the linked list of addresses | ||
870 | * associated with this dev structure. | ||
871 | */ | ||
872 | |||
873 | static inline void make_mc_bits(u8 *bits, struct net_device *dev) | ||
874 | { | ||
875 | struct netdev_hw_addr *ha; | ||
876 | |||
877 | netdev_for_each_mc_addr(ha, dev) { | ||
878 | u32 crc = ether_crc(ETH_ALEN, ha->addr); | ||
879 | /* | ||
880 | * The 8390 uses the 6 most significant bits of the | ||
881 | * CRC to index the multicast table. | ||
882 | */ | ||
883 | bits[crc>>29] |= (1<<((crc>>26)&7)); | ||
884 | } | ||
885 | } | ||
886 | |||
887 | /** | ||
888 | * do_set_multicast_list - set/clear multicast filter | ||
889 | * @dev: net device for which multicast filter is adjusted | ||
890 | * | ||
891 | * Set or clear the multicast filter for this adaptor. May be called | ||
892 | * from a BH in 2.1.x. Must be called with lock held. | ||
893 | */ | ||
894 | |||
895 | static void do_set_multicast_list(struct net_device *dev) | ||
896 | { | ||
897 | unsigned long e8390_base = dev->base_addr; | ||
898 | int i; | ||
899 | struct ei_device *ei_local = netdev_priv(dev); | ||
900 | |||
901 | if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) { | ||
902 | memset(ei_local->mcfilter, 0, 8); | ||
903 | if (!netdev_mc_empty(dev)) | ||
904 | make_mc_bits(ei_local->mcfilter, dev); | ||
905 | } else | ||
906 | memset(ei_local->mcfilter, 0xFF, 8); /* mcast set to accept-all */ | ||
907 | |||
908 | /* | ||
909 | * DP8390 manuals don't specify any magic sequence for altering | ||
910 | * the multicast regs on an already running card. To be safe, we | ||
911 | * ensure multicast mode is off prior to loading up the new hash | ||
912 | * table. If this proves to be not enough, we can always resort | ||
913 | * to stopping the NIC, loading the table and then restarting. | ||
914 | * | ||
915 | * Bug Alert! The MC regs on the SMC 83C690 (SMC Elite and SMC | ||
916 | * Elite16) appear to be write-only. The NS 8390 data sheet lists | ||
917 | * them as r/w so this is a bug. The SMC 83C790 (SMC Ultra and | ||
918 | * Ultra32 EISA) appears to have this bug fixed. | ||
919 | */ | ||
920 | |||
921 | if (netif_running(dev)) | ||
922 | ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); | ||
923 | ei_outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD); | ||
924 | for (i = 0; i < 8; i++) { | ||
925 | ei_outb_p(ei_local->mcfilter[i], e8390_base + EN1_MULT_SHIFT(i)); | ||
926 | #ifndef BUG_83C690 | ||
927 | if (ei_inb_p(e8390_base + EN1_MULT_SHIFT(i)) != ei_local->mcfilter[i]) | ||
928 | netdev_err(dev, "Multicast filter read/write mismap %d\n", | ||
929 | i); | ||
930 | #endif | ||
931 | } | ||
932 | ei_outb_p(E8390_NODMA + E8390_PAGE0, e8390_base + E8390_CMD); | ||
933 | |||
934 | if (dev->flags&IFF_PROMISC) | ||
935 | ei_outb_p(E8390_RXCONFIG | 0x18, e8390_base + EN0_RXCR); | ||
936 | else if (dev->flags & IFF_ALLMULTI || !netdev_mc_empty(dev)) | ||
937 | ei_outb_p(E8390_RXCONFIG | 0x08, e8390_base + EN0_RXCR); | ||
938 | else | ||
939 | ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); | ||
940 | } | ||
941 | |||
942 | /* | ||
943 | * Called without lock held. This is invoked from user context and may | ||
944 | * be parallel to just about everything else. Its also fairly quick and | ||
945 | * not called too often. Must protect against both bh and irq users | ||
946 | */ | ||
947 | |||
948 | static void __ei_set_multicast_list(struct net_device *dev) | ||
949 | { | ||
950 | unsigned long flags; | ||
951 | struct ei_device *ei_local = netdev_priv(dev); | ||
952 | |||
953 | spin_lock_irqsave(&ei_local->page_lock, flags); | ||
954 | do_set_multicast_list(dev); | ||
955 | spin_unlock_irqrestore(&ei_local->page_lock, flags); | ||
956 | } | ||
957 | |||
958 | /** | ||
959 | * ethdev_setup - init rest of 8390 device struct | ||
960 | * @dev: network device structure to init | ||
961 | * | ||
962 | * Initialize the rest of the 8390 device structure. Do NOT __init | ||
963 | * this, as it is used by 8390 based modular drivers too. | ||
964 | */ | ||
965 | |||
966 | static void ethdev_setup(struct net_device *dev) | ||
967 | { | ||
968 | struct ei_device *ei_local = netdev_priv(dev); | ||
969 | if (ei_debug > 1) | ||
970 | printk(version); | ||
971 | |||
972 | ether_setup(dev); | ||
973 | |||
974 | spin_lock_init(&ei_local->page_lock); | ||
975 | } | ||
976 | |||
977 | /** | ||
978 | * alloc_ei_netdev - alloc_etherdev counterpart for 8390 | ||
979 | * @size: extra bytes to allocate | ||
980 | * | ||
981 | * Allocate 8390-specific net_device. | ||
982 | */ | ||
983 | static struct net_device *____alloc_ei_netdev(int size) | ||
984 | { | ||
985 | return alloc_netdev(sizeof(struct ei_device) + size, "eth%d", | ||
986 | ethdev_setup); | ||
987 | } | ||
988 | |||
989 | |||
990 | |||
991 | |||
992 | /* This page of functions should be 8390 generic */ | ||
993 | /* Follow National Semi's recommendations for initializing the "NIC". */ | ||
994 | |||
995 | /** | ||
996 | * NS8390_init - initialize 8390 hardware | ||
997 | * @dev: network device to initialize | ||
998 | * @startp: boolean. non-zero value to initiate chip processing | ||
999 | * | ||
1000 | * Must be called with lock held. | ||
1001 | */ | ||
1002 | |||
1003 | static void __NS8390_init(struct net_device *dev, int startp) | ||
1004 | { | ||
1005 | unsigned long e8390_base = dev->base_addr; | ||
1006 | struct ei_device *ei_local = netdev_priv(dev); | ||
1007 | int i; | ||
1008 | int endcfg = ei_local->word16 | ||
1009 | ? (0x48 | ENDCFG_WTS | (ei_local->bigendian ? ENDCFG_BOS : 0)) | ||
1010 | : 0x48; | ||
1011 | |||
1012 | if (sizeof(struct e8390_pkt_hdr) != 4) | ||
1013 | panic("8390.c: header struct mispacked\n"); | ||
1014 | /* Follow National Semi's recommendations for initing the DP83902. */ | ||
1015 | ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); /* 0x21 */ | ||
1016 | ei_outb_p(endcfg, e8390_base + EN0_DCFG); /* 0x48 or 0x49 */ | ||
1017 | /* Clear the remote byte count registers. */ | ||
1018 | ei_outb_p(0x00, e8390_base + EN0_RCNTLO); | ||
1019 | ei_outb_p(0x00, e8390_base + EN0_RCNTHI); | ||
1020 | /* Set to monitor and loopback mode -- this is vital!. */ | ||
1021 | ei_outb_p(E8390_RXOFF, e8390_base + EN0_RXCR); /* 0x20 */ | ||
1022 | ei_outb_p(E8390_TXOFF, e8390_base + EN0_TXCR); /* 0x02 */ | ||
1023 | /* Set the transmit page and receive ring. */ | ||
1024 | ei_outb_p(ei_local->tx_start_page, e8390_base + EN0_TPSR); | ||
1025 | ei_local->tx1 = ei_local->tx2 = 0; | ||
1026 | ei_outb_p(ei_local->rx_start_page, e8390_base + EN0_STARTPG); | ||
1027 | ei_outb_p(ei_local->stop_page-1, e8390_base + EN0_BOUNDARY); /* 3c503 says 0x3f,NS0x26*/ | ||
1028 | ei_local->current_page = ei_local->rx_start_page; /* assert boundary+1 */ | ||
1029 | ei_outb_p(ei_local->stop_page, e8390_base + EN0_STOPPG); | ||
1030 | /* Clear the pending interrupts and mask. */ | ||
1031 | ei_outb_p(0xFF, e8390_base + EN0_ISR); | ||
1032 | ei_outb_p(0x00, e8390_base + EN0_IMR); | ||
1033 | |||
1034 | /* Copy the station address into the DS8390 registers. */ | ||
1035 | |||
1036 | ei_outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, e8390_base+E8390_CMD); /* 0x61 */ | ||
1037 | for (i = 0; i < 6; i++) { | ||
1038 | ei_outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS_SHIFT(i)); | ||
1039 | if (ei_debug > 1 && | ||
1040 | ei_inb_p(e8390_base + EN1_PHYS_SHIFT(i)) != dev->dev_addr[i]) | ||
1041 | netdev_err(dev, "Hw. address read/write mismap %d\n", i); | ||
1042 | } | ||
1043 | |||
1044 | ei_outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG); | ||
1045 | ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD); | ||
1046 | |||
1047 | ei_local->tx1 = ei_local->tx2 = 0; | ||
1048 | ei_local->txing = 0; | ||
1049 | |||
1050 | if (startp) { | ||
1051 | ei_outb_p(0xff, e8390_base + EN0_ISR); | ||
1052 | ei_outb_p(ENISR_ALL, e8390_base + EN0_IMR); | ||
1053 | ei_outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD); | ||
1054 | ei_outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); /* xmit on. */ | ||
1055 | /* 3c503 TechMan says rxconfig only after the NIC is started. */ | ||
1056 | ei_outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR); /* rx on, */ | ||
1057 | do_set_multicast_list(dev); /* (re)load the mcast table */ | ||
1058 | } | ||
1059 | } | ||
1060 | |||
1061 | /* Trigger a transmit start, assuming the length is valid. | ||
1062 | Always called with the page lock held */ | ||
1063 | |||
1064 | static void NS8390_trigger_send(struct net_device *dev, unsigned int length, | ||
1065 | int start_page) | ||
1066 | { | ||
1067 | unsigned long e8390_base = dev->base_addr; | ||
1068 | struct ei_device *ei_local __attribute((unused)) = netdev_priv(dev); | ||
1069 | |||
1070 | ei_outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD); | ||
1071 | |||
1072 | if (ei_inb_p(e8390_base + E8390_CMD) & E8390_TRANS) { | ||
1073 | netdev_warn(dev, "trigger_send() called with the transmitter busy\n"); | ||
1074 | return; | ||
1075 | } | ||
1076 | ei_outb_p(length & 0xff, e8390_base + EN0_TCNTLO); | ||
1077 | ei_outb_p(length >> 8, e8390_base + EN0_TCNTHI); | ||
1078 | ei_outb_p(start_page, e8390_base + EN0_TPSR); | ||
1079 | ei_outb_p(E8390_NODMA+E8390_TRANS+E8390_START, e8390_base+E8390_CMD); | ||
1080 | } | ||
diff --git a/drivers/net/ethernet/8390/lne390.c b/drivers/net/ethernet/8390/lne390.c new file mode 100644 index 000000000000..f9888d20177b --- /dev/null +++ b/drivers/net/ethernet/8390/lne390.c | |||
@@ -0,0 +1,434 @@ | |||
1 | /* | ||
2 | lne390.c | ||
3 | |||
4 | Linux driver for Mylex LNE390 EISA Network Adapter | ||
5 | |||
6 | Copyright (C) 1996-1998, Paul Gortmaker. | ||
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 | Information and Code Sources: | ||
12 | |||
13 | 1) Based upon framework of es3210 driver. | ||
14 | 2) The existing myriad of other Linux 8390 drivers by Donald Becker. | ||
15 | 3) Russ Nelson's asm packet driver provided additional info. | ||
16 | 4) Info for getting IRQ and sh-mem gleaned from the EISA cfg files. | ||
17 | |||
18 | The LNE390 is an EISA shared memory NS8390 implementation. Note | ||
19 | that all memory copies to/from the board must be 32bit transfers. | ||
20 | There are two versions of the card: the lne390a and the lne390b. | ||
21 | Going by the EISA cfg files, the "a" has jumpers to select between | ||
22 | BNC/AUI, but the "b" also has RJ-45 and selection is via the SCU. | ||
23 | The shared memory address selection is also slightly different. | ||
24 | Note that shared memory address > 1MB are supported with this driver. | ||
25 | |||
26 | You can try <http://www.mylex.com> if you want more info, as I've | ||
27 | never even seen one of these cards. :) | ||
28 | |||
29 | Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 2000/09/01 | ||
30 | - get rid of check_region | ||
31 | - no need to check if dev == NULL in lne390_probe1 | ||
32 | */ | ||
33 | |||
34 | static const char *version = | ||
35 | "lne390.c: Driver revision v0.99.1, 01/09/2000\n"; | ||
36 | |||
37 | #include <linux/module.h> | ||
38 | #include <linux/eisa.h> | ||
39 | #include <linux/kernel.h> | ||
40 | #include <linux/errno.h> | ||
41 | #include <linux/string.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/init.h> | ||
44 | #include <linux/interrupt.h> | ||
45 | #include <linux/netdevice.h> | ||
46 | #include <linux/etherdevice.h> | ||
47 | |||
48 | #include <asm/io.h> | ||
49 | #include <asm/system.h> | ||
50 | |||
51 | #include "8390.h" | ||
52 | |||
53 | #define DRV_NAME "lne390" | ||
54 | |||
55 | static int lne390_probe1(struct net_device *dev, int ioaddr); | ||
56 | |||
57 | static void lne390_reset_8390(struct net_device *dev); | ||
58 | |||
59 | static void lne390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); | ||
60 | static void lne390_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); | ||
61 | static void lne390_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); | ||
62 | |||
63 | #define LNE390_START_PG 0x00 /* First page of TX buffer */ | ||
64 | #define LNE390_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
65 | |||
66 | #define LNE390_ID_PORT 0xc80 /* Same for all EISA cards */ | ||
67 | #define LNE390_IO_EXTENT 0x20 | ||
68 | #define LNE390_SA_PROM 0x16 /* Start of e'net addr. */ | ||
69 | #define LNE390_RESET_PORT 0xc84 /* From the pkt driver source */ | ||
70 | #define LNE390_NIC_OFFSET 0x00 /* Hello, the 8390 is *here* */ | ||
71 | |||
72 | #define LNE390_ADDR0 0x00 /* 3 byte vendor prefix */ | ||
73 | #define LNE390_ADDR1 0x80 | ||
74 | #define LNE390_ADDR2 0xe5 | ||
75 | |||
76 | #define LNE390_ID0 0x10009835 /* 0x3598 = 01101 01100 11000 = mlx */ | ||
77 | #define LNE390_ID1 0x11009835 /* above is the 390A, this is 390B */ | ||
78 | |||
79 | #define LNE390_CFG1 0xc84 /* NB: 0xc84 is also "reset" port. */ | ||
80 | #define LNE390_CFG2 0xc90 | ||
81 | |||
82 | /* | ||
83 | * You can OR any of the following bits together and assign it | ||
84 | * to LNE390_DEBUG to get verbose driver info during operation. | ||
85 | * Currently only the probe one is implemented. | ||
86 | */ | ||
87 | |||
88 | #define LNE390_D_PROBE 0x01 | ||
89 | #define LNE390_D_RX_PKT 0x02 | ||
90 | #define LNE390_D_TX_PKT 0x04 | ||
91 | #define LNE390_D_IRQ 0x08 | ||
92 | |||
93 | #define LNE390_DEBUG 0 | ||
94 | |||
95 | static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3}; | ||
96 | static unsigned int shmem_mapA[] __initdata = {0xff, 0xfe, 0xfd, 0xfff, 0xffe, 0xffc, 0x0d, 0x0}; | ||
97 | static unsigned int shmem_mapB[] __initdata = {0xff, 0xfe, 0x0e, 0xfff, 0xffe, 0xffc, 0x0d, 0x0}; | ||
98 | |||
99 | /* | ||
100 | * Probe for the card. The best way is to read the EISA ID if it | ||
101 | * is known. Then we can check the prefix of the station address | ||
102 | * PROM for a match against the value assigned to Mylex. | ||
103 | */ | ||
104 | |||
105 | static int __init do_lne390_probe(struct net_device *dev) | ||
106 | { | ||
107 | unsigned short ioaddr = dev->base_addr; | ||
108 | int irq = dev->irq; | ||
109 | int mem_start = dev->mem_start; | ||
110 | int ret; | ||
111 | |||
112 | if (ioaddr > 0x1ff) { /* Check a single specified location. */ | ||
113 | if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME)) | ||
114 | return -EBUSY; | ||
115 | ret = lne390_probe1(dev, ioaddr); | ||
116 | if (ret) | ||
117 | release_region(ioaddr, LNE390_IO_EXTENT); | ||
118 | return ret; | ||
119 | } | ||
120 | else if (ioaddr > 0) /* Don't probe at all. */ | ||
121 | return -ENXIO; | ||
122 | |||
123 | if (!EISA_bus) { | ||
124 | #if LNE390_DEBUG & LNE390_D_PROBE | ||
125 | printk("lne390-debug: Not an EISA bus. Not probing high ports.\n"); | ||
126 | #endif | ||
127 | return -ENXIO; | ||
128 | } | ||
129 | |||
130 | /* EISA spec allows for up to 16 slots, but 8 is typical. */ | ||
131 | for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { | ||
132 | if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME)) | ||
133 | continue; | ||
134 | if (lne390_probe1(dev, ioaddr) == 0) | ||
135 | return 0; | ||
136 | release_region(ioaddr, LNE390_IO_EXTENT); | ||
137 | dev->irq = irq; | ||
138 | dev->mem_start = mem_start; | ||
139 | } | ||
140 | |||
141 | return -ENODEV; | ||
142 | } | ||
143 | |||
144 | #ifndef MODULE | ||
145 | struct net_device * __init lne390_probe(int unit) | ||
146 | { | ||
147 | struct net_device *dev = alloc_ei_netdev(); | ||
148 | int err; | ||
149 | |||
150 | if (!dev) | ||
151 | return ERR_PTR(-ENOMEM); | ||
152 | |||
153 | sprintf(dev->name, "eth%d", unit); | ||
154 | netdev_boot_setup_check(dev); | ||
155 | |||
156 | err = do_lne390_probe(dev); | ||
157 | if (err) | ||
158 | goto out; | ||
159 | return dev; | ||
160 | out: | ||
161 | free_netdev(dev); | ||
162 | return ERR_PTR(err); | ||
163 | } | ||
164 | #endif | ||
165 | |||
166 | static int __init lne390_probe1(struct net_device *dev, int ioaddr) | ||
167 | { | ||
168 | int i, revision, ret; | ||
169 | unsigned long eisa_id; | ||
170 | |||
171 | if (inb_p(ioaddr + LNE390_ID_PORT) == 0xff) return -ENODEV; | ||
172 | |||
173 | #if LNE390_DEBUG & LNE390_D_PROBE | ||
174 | printk("lne390-debug: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + LNE390_ID_PORT)); | ||
175 | printk("lne390-debug: config regs: %#x %#x\n", | ||
176 | inb(ioaddr + LNE390_CFG1), inb(ioaddr + LNE390_CFG2)); | ||
177 | #endif | ||
178 | |||
179 | |||
180 | /* Check the EISA ID of the card. */ | ||
181 | eisa_id = inl(ioaddr + LNE390_ID_PORT); | ||
182 | if ((eisa_id != LNE390_ID0) && (eisa_id != LNE390_ID1)) { | ||
183 | return -ENODEV; | ||
184 | } | ||
185 | |||
186 | revision = (eisa_id >> 24) & 0x01; /* 0 = rev A, 1 rev B */ | ||
187 | |||
188 | #if 0 | ||
189 | /* Check the Mylex vendor ID as well. Not really required. */ | ||
190 | if (inb(ioaddr + LNE390_SA_PROM + 0) != LNE390_ADDR0 | ||
191 | || inb(ioaddr + LNE390_SA_PROM + 1) != LNE390_ADDR1 | ||
192 | || inb(ioaddr + LNE390_SA_PROM + 2) != LNE390_ADDR2 ) { | ||
193 | printk("lne390.c: card not found"); | ||
194 | for(i = 0; i < ETHER_ADDR_LEN; i++) | ||
195 | printk(" %02x", inb(ioaddr + LNE390_SA_PROM + i)); | ||
196 | printk(" (invalid prefix).\n"); | ||
197 | return -ENODEV; | ||
198 | } | ||
199 | #endif | ||
200 | |||
201 | for(i = 0; i < ETHER_ADDR_LEN; i++) | ||
202 | dev->dev_addr[i] = inb(ioaddr + LNE390_SA_PROM + i); | ||
203 | printk("lne390.c: LNE390%X in EISA slot %d, address %pM.\n", | ||
204 | 0xa+revision, ioaddr/0x1000, dev->dev_addr); | ||
205 | |||
206 | printk("lne390.c: "); | ||
207 | |||
208 | /* Snarf the interrupt now. CFG file has them all listed as `edge' with share=NO */ | ||
209 | if (dev->irq == 0) { | ||
210 | unsigned char irq_reg = inb(ioaddr + LNE390_CFG2) >> 3; | ||
211 | dev->irq = irq_map[irq_reg & 0x07]; | ||
212 | printk("using"); | ||
213 | } else { | ||
214 | /* This is useless unless we reprogram the card here too */ | ||
215 | if (dev->irq == 2) dev->irq = 9; /* Doh! */ | ||
216 | printk("assigning"); | ||
217 | } | ||
218 | printk(" IRQ %d,", dev->irq); | ||
219 | |||
220 | if ((ret = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev))) { | ||
221 | printk (" unable to get IRQ %d.\n", dev->irq); | ||
222 | return ret; | ||
223 | } | ||
224 | |||
225 | if (dev->mem_start == 0) { | ||
226 | unsigned char mem_reg = inb(ioaddr + LNE390_CFG2) & 0x07; | ||
227 | |||
228 | if (revision) /* LNE390B */ | ||
229 | dev->mem_start = shmem_mapB[mem_reg] * 0x10000; | ||
230 | else /* LNE390A */ | ||
231 | dev->mem_start = shmem_mapA[mem_reg] * 0x10000; | ||
232 | printk(" using "); | ||
233 | } else { | ||
234 | /* Should check for value in shmem_map and reprogram the card to use it */ | ||
235 | dev->mem_start &= 0xfff0000; | ||
236 | printk(" assigning "); | ||
237 | } | ||
238 | |||
239 | printk("%dkB memory at physical address %#lx\n", | ||
240 | LNE390_STOP_PG/4, dev->mem_start); | ||
241 | |||
242 | /* | ||
243 | BEWARE!! Some dain-bramaged EISA SCUs will allow you to put | ||
244 | the card mem within the region covered by `normal' RAM !!! | ||
245 | |||
246 | ioremap() will fail in that case. | ||
247 | */ | ||
248 | ei_status.mem = ioremap(dev->mem_start, LNE390_STOP_PG*0x100); | ||
249 | if (!ei_status.mem) { | ||
250 | printk(KERN_ERR "lne390.c: Unable to remap card memory above 1MB !!\n"); | ||
251 | printk(KERN_ERR "lne390.c: Try using EISA SCU to set memory below 1MB.\n"); | ||
252 | printk(KERN_ERR "lne390.c: Driver NOT installed.\n"); | ||
253 | ret = -EAGAIN; | ||
254 | goto cleanup; | ||
255 | } | ||
256 | printk("lne390.c: remapped %dkB card memory to virtual address %p\n", | ||
257 | LNE390_STOP_PG/4, ei_status.mem); | ||
258 | |||
259 | dev->mem_start = (unsigned long)ei_status.mem; | ||
260 | dev->mem_end = dev->mem_start + (LNE390_STOP_PG - LNE390_START_PG)*256; | ||
261 | |||
262 | /* The 8390 offset is zero for the LNE390 */ | ||
263 | dev->base_addr = ioaddr; | ||
264 | |||
265 | ei_status.name = "LNE390"; | ||
266 | ei_status.tx_start_page = LNE390_START_PG; | ||
267 | ei_status.rx_start_page = LNE390_START_PG + TX_PAGES; | ||
268 | ei_status.stop_page = LNE390_STOP_PG; | ||
269 | ei_status.word16 = 1; | ||
270 | |||
271 | if (ei_debug > 0) | ||
272 | printk(version); | ||
273 | |||
274 | ei_status.reset_8390 = &lne390_reset_8390; | ||
275 | ei_status.block_input = &lne390_block_input; | ||
276 | ei_status.block_output = &lne390_block_output; | ||
277 | ei_status.get_8390_hdr = &lne390_get_8390_hdr; | ||
278 | |||
279 | dev->netdev_ops = &ei_netdev_ops; | ||
280 | NS8390_init(dev, 0); | ||
281 | |||
282 | ret = register_netdev(dev); | ||
283 | if (ret) | ||
284 | goto unmap; | ||
285 | return 0; | ||
286 | unmap: | ||
287 | if (ei_status.reg0) | ||
288 | iounmap(ei_status.mem); | ||
289 | cleanup: | ||
290 | free_irq(dev->irq, dev); | ||
291 | return ret; | ||
292 | } | ||
293 | |||
294 | /* | ||
295 | * Reset as per the packet driver method. Judging by the EISA cfg | ||
296 | * file, this just toggles the "Board Enable" bits (bit 2 and 0). | ||
297 | */ | ||
298 | |||
299 | static void lne390_reset_8390(struct net_device *dev) | ||
300 | { | ||
301 | unsigned short ioaddr = dev->base_addr; | ||
302 | |||
303 | outb(0x04, ioaddr + LNE390_RESET_PORT); | ||
304 | if (ei_debug > 1) printk("%s: resetting the LNE390...", dev->name); | ||
305 | |||
306 | mdelay(2); | ||
307 | |||
308 | ei_status.txing = 0; | ||
309 | outb(0x01, ioaddr + LNE390_RESET_PORT); | ||
310 | if (ei_debug > 1) printk("reset done\n"); | ||
311 | } | ||
312 | |||
313 | /* | ||
314 | * Note: In the following three functions is the implicit assumption | ||
315 | * that the associated memcpy will only use "rep; movsl" as long as | ||
316 | * we keep the counts as some multiple of doublewords. This is a | ||
317 | * requirement of the hardware, and also prevents us from using | ||
318 | * eth_io_copy_and_sum() since we can't guarantee it will limit | ||
319 | * itself to doubleword access. | ||
320 | */ | ||
321 | |||
322 | /* | ||
323 | * Grab the 8390 specific header. Similar to the block_input routine, but | ||
324 | * we don't need to be concerned with ring wrap as the header will be at | ||
325 | * the start of a page, so we optimize accordingly. (A single doubleword.) | ||
326 | */ | ||
327 | |||
328 | static void | ||
329 | lne390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
330 | { | ||
331 | void __iomem *hdr_start = ei_status.mem + ((ring_page - LNE390_START_PG)<<8); | ||
332 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
333 | hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */ | ||
334 | } | ||
335 | |||
336 | /* | ||
337 | * Block input and output are easy on shared memory ethercards, the only | ||
338 | * complication is when the ring buffer wraps. The count will already | ||
339 | * be rounded up to a doubleword value via lne390_get_8390_hdr() above. | ||
340 | */ | ||
341 | |||
342 | static void lne390_block_input(struct net_device *dev, int count, struct sk_buff *skb, | ||
343 | int ring_offset) | ||
344 | { | ||
345 | void __iomem *xfer_start = ei_status.mem + ring_offset - (LNE390_START_PG<<8); | ||
346 | |||
347 | if (ring_offset + count > (LNE390_STOP_PG<<8)) { | ||
348 | /* Packet wraps over end of ring buffer. */ | ||
349 | int semi_count = (LNE390_STOP_PG<<8) - ring_offset; | ||
350 | memcpy_fromio(skb->data, xfer_start, semi_count); | ||
351 | count -= semi_count; | ||
352 | memcpy_fromio(skb->data + semi_count, | ||
353 | ei_status.mem + (TX_PAGES<<8), count); | ||
354 | } else { | ||
355 | /* Packet is in one chunk. */ | ||
356 | memcpy_fromio(skb->data, xfer_start, count); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | static void lne390_block_output(struct net_device *dev, int count, | ||
361 | const unsigned char *buf, int start_page) | ||
362 | { | ||
363 | void __iomem *shmem = ei_status.mem + ((start_page - LNE390_START_PG)<<8); | ||
364 | |||
365 | count = (count + 3) & ~3; /* Round up to doubleword */ | ||
366 | memcpy_toio(shmem, buf, count); | ||
367 | } | ||
368 | |||
369 | |||
370 | #ifdef MODULE | ||
371 | #define MAX_LNE_CARDS 4 /* Max number of LNE390 cards per module */ | ||
372 | static struct net_device *dev_lne[MAX_LNE_CARDS]; | ||
373 | static int io[MAX_LNE_CARDS]; | ||
374 | static int irq[MAX_LNE_CARDS]; | ||
375 | static int mem[MAX_LNE_CARDS]; | ||
376 | |||
377 | module_param_array(io, int, NULL, 0); | ||
378 | module_param_array(irq, int, NULL, 0); | ||
379 | module_param_array(mem, int, NULL, 0); | ||
380 | MODULE_PARM_DESC(io, "I/O base address(es)"); | ||
381 | MODULE_PARM_DESC(irq, "IRQ number(s)"); | ||
382 | MODULE_PARM_DESC(mem, "memory base address(es)"); | ||
383 | MODULE_DESCRIPTION("Mylex LNE390A/B EISA Ethernet driver"); | ||
384 | MODULE_LICENSE("GPL"); | ||
385 | |||
386 | int __init init_module(void) | ||
387 | { | ||
388 | struct net_device *dev; | ||
389 | int this_dev, found = 0; | ||
390 | |||
391 | for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) { | ||
392 | if (io[this_dev] == 0 && this_dev != 0) | ||
393 | break; | ||
394 | dev = alloc_ei_netdev(); | ||
395 | if (!dev) | ||
396 | break; | ||
397 | dev->irq = irq[this_dev]; | ||
398 | dev->base_addr = io[this_dev]; | ||
399 | dev->mem_start = mem[this_dev]; | ||
400 | if (do_lne390_probe(dev) == 0) { | ||
401 | dev_lne[found++] = dev; | ||
402 | continue; | ||
403 | } | ||
404 | free_netdev(dev); | ||
405 | printk(KERN_WARNING "lne390.c: No LNE390 card found (i/o = 0x%x).\n", io[this_dev]); | ||
406 | break; | ||
407 | } | ||
408 | if (found) | ||
409 | return 0; | ||
410 | return -ENXIO; | ||
411 | } | ||
412 | |||
413 | static void cleanup_card(struct net_device *dev) | ||
414 | { | ||
415 | free_irq(dev->irq, dev); | ||
416 | release_region(dev->base_addr, LNE390_IO_EXTENT); | ||
417 | iounmap(ei_status.mem); | ||
418 | } | ||
419 | |||
420 | void __exit cleanup_module(void) | ||
421 | { | ||
422 | int this_dev; | ||
423 | |||
424 | for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) { | ||
425 | struct net_device *dev = dev_lne[this_dev]; | ||
426 | if (dev) { | ||
427 | unregister_netdev(dev); | ||
428 | cleanup_card(dev); | ||
429 | free_netdev(dev); | ||
430 | } | ||
431 | } | ||
432 | } | ||
433 | #endif /* MODULE */ | ||
434 | |||
diff --git a/drivers/net/ethernet/8390/mac8390.c b/drivers/net/ethernet/8390/mac8390.c new file mode 100644 index 000000000000..f84f5e6ededb --- /dev/null +++ b/drivers/net/ethernet/8390/mac8390.c | |||
@@ -0,0 +1,874 @@ | |||
1 | /* mac8390.c: New driver for 8390-based Nubus (or Nubus-alike) | ||
2 | Ethernet cards on Linux */ | ||
3 | /* Based on the former daynaport.c driver, by Alan Cox. Some code | ||
4 | taken from or inspired by skeleton.c by Donald Becker, acenic.c by | ||
5 | Jes Sorensen, and ne2k-pci.c by Donald Becker and Paul Gortmaker. | ||
6 | |||
7 | This software may be used and distributed according to the terms of | ||
8 | the GNU Public License, incorporated herein by reference. */ | ||
9 | |||
10 | /* 2000-02-28: support added for Dayna and Kinetics cards by | ||
11 | A.G.deWijn@phys.uu.nl */ | ||
12 | /* 2000-04-04: support added for Dayna2 by bart@etpmod.phys.tue.nl */ | ||
13 | /* 2001-04-18: support for DaynaPort E/LC-M by rayk@knightsmanor.org */ | ||
14 | /* 2001-05-15: support for Cabletron ported from old daynaport driver | ||
15 | * and fixed access to Sonic Sys card which masquerades as a Farallon | ||
16 | * by rayk@knightsmanor.org */ | ||
17 | /* 2002-12-30: Try to support more cards, some clues from NetBSD driver */ | ||
18 | /* 2003-12-26: Make sure Asante cards always work. */ | ||
19 | |||
20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/types.h> | ||
25 | #include <linux/fcntl.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/ptrace.h> | ||
28 | #include <linux/ioport.h> | ||
29 | #include <linux/nubus.h> | ||
30 | #include <linux/in.h> | ||
31 | #include <linux/string.h> | ||
32 | #include <linux/errno.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/netdevice.h> | ||
35 | #include <linux/etherdevice.h> | ||
36 | #include <linux/skbuff.h> | ||
37 | #include <linux/bitops.h> | ||
38 | #include <linux/io.h> | ||
39 | |||
40 | #include <asm/system.h> | ||
41 | #include <asm/dma.h> | ||
42 | #include <asm/hwtest.h> | ||
43 | #include <asm/macints.h> | ||
44 | |||
45 | static char version[] = | ||
46 | "v0.4 2001-05-15 David Huggins-Daines <dhd@debian.org> and others\n"; | ||
47 | |||
48 | #define EI_SHIFT(x) (ei_local->reg_offset[x]) | ||
49 | #define ei_inb(port) in_8(port) | ||
50 | #define ei_outb(val, port) out_8(port, val) | ||
51 | #define ei_inb_p(port) in_8(port) | ||
52 | #define ei_outb_p(val, port) out_8(port, val) | ||
53 | |||
54 | #include "lib8390.c" | ||
55 | |||
56 | #define WD_START_PG 0x00 /* First page of TX buffer */ | ||
57 | #define CABLETRON_RX_START_PG 0x00 /* First page of RX buffer */ | ||
58 | #define CABLETRON_RX_STOP_PG 0x30 /* Last page +1 of RX ring */ | ||
59 | #define CABLETRON_TX_START_PG CABLETRON_RX_STOP_PG | ||
60 | /* First page of TX buffer */ | ||
61 | |||
62 | /* | ||
63 | * Unfortunately it seems we have to hardcode these for the moment | ||
64 | * Shouldn't the card know about this? | ||
65 | * Does anyone know where to read it off the card? | ||
66 | * Do we trust the data provided by the card? | ||
67 | */ | ||
68 | |||
69 | #define DAYNA_8390_BASE 0x80000 | ||
70 | #define DAYNA_8390_MEM 0x00000 | ||
71 | |||
72 | #define CABLETRON_8390_BASE 0x90000 | ||
73 | #define CABLETRON_8390_MEM 0x00000 | ||
74 | |||
75 | #define INTERLAN_8390_BASE 0xE0000 | ||
76 | #define INTERLAN_8390_MEM 0xD0000 | ||
77 | |||
78 | enum mac8390_type { | ||
79 | MAC8390_NONE = -1, | ||
80 | MAC8390_APPLE, | ||
81 | MAC8390_ASANTE, | ||
82 | MAC8390_FARALLON, | ||
83 | MAC8390_CABLETRON, | ||
84 | MAC8390_DAYNA, | ||
85 | MAC8390_INTERLAN, | ||
86 | MAC8390_KINETICS, | ||
87 | }; | ||
88 | |||
89 | static const char *cardname[] = { | ||
90 | "apple", | ||
91 | "asante", | ||
92 | "farallon", | ||
93 | "cabletron", | ||
94 | "dayna", | ||
95 | "interlan", | ||
96 | "kinetics", | ||
97 | }; | ||
98 | |||
99 | static const int word16[] = { | ||
100 | 1, /* apple */ | ||
101 | 1, /* asante */ | ||
102 | 1, /* farallon */ | ||
103 | 1, /* cabletron */ | ||
104 | 0, /* dayna */ | ||
105 | 1, /* interlan */ | ||
106 | 0, /* kinetics */ | ||
107 | }; | ||
108 | |||
109 | /* on which cards do we use NuBus resources? */ | ||
110 | static const int useresources[] = { | ||
111 | 1, /* apple */ | ||
112 | 1, /* asante */ | ||
113 | 1, /* farallon */ | ||
114 | 0, /* cabletron */ | ||
115 | 0, /* dayna */ | ||
116 | 0, /* interlan */ | ||
117 | 0, /* kinetics */ | ||
118 | }; | ||
119 | |||
120 | enum mac8390_access { | ||
121 | ACCESS_UNKNOWN = 0, | ||
122 | ACCESS_32, | ||
123 | ACCESS_16, | ||
124 | }; | ||
125 | |||
126 | extern int mac8390_memtest(struct net_device *dev); | ||
127 | static int mac8390_initdev(struct net_device *dev, struct nubus_dev *ndev, | ||
128 | enum mac8390_type type); | ||
129 | |||
130 | static int mac8390_open(struct net_device *dev); | ||
131 | static int mac8390_close(struct net_device *dev); | ||
132 | static void mac8390_no_reset(struct net_device *dev); | ||
133 | static void interlan_reset(struct net_device *dev); | ||
134 | |||
135 | /* Sane (32-bit chunk memory read/write) - Some Farallon and Apple do this*/ | ||
136 | static void sane_get_8390_hdr(struct net_device *dev, | ||
137 | struct e8390_pkt_hdr *hdr, int ring_page); | ||
138 | static void sane_block_input(struct net_device *dev, int count, | ||
139 | struct sk_buff *skb, int ring_offset); | ||
140 | static void sane_block_output(struct net_device *dev, int count, | ||
141 | const unsigned char *buf, const int start_page); | ||
142 | |||
143 | /* dayna_memcpy to and from card */ | ||
144 | static void dayna_memcpy_fromcard(struct net_device *dev, void *to, | ||
145 | int from, int count); | ||
146 | static void dayna_memcpy_tocard(struct net_device *dev, int to, | ||
147 | const void *from, int count); | ||
148 | |||
149 | /* Dayna - Dayna/Kinetics use this */ | ||
150 | static void dayna_get_8390_hdr(struct net_device *dev, | ||
151 | struct e8390_pkt_hdr *hdr, int ring_page); | ||
152 | static void dayna_block_input(struct net_device *dev, int count, | ||
153 | struct sk_buff *skb, int ring_offset); | ||
154 | static void dayna_block_output(struct net_device *dev, int count, | ||
155 | const unsigned char *buf, int start_page); | ||
156 | |||
157 | #define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c)) | ||
158 | #define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c)) | ||
159 | |||
160 | #define memcmp_withio(a, b, c) memcmp((a), (void *)(b), (c)) | ||
161 | |||
162 | /* Slow Sane (16-bit chunk memory read/write) Cabletron uses this */ | ||
163 | static void slow_sane_get_8390_hdr(struct net_device *dev, | ||
164 | struct e8390_pkt_hdr *hdr, int ring_page); | ||
165 | static void slow_sane_block_input(struct net_device *dev, int count, | ||
166 | struct sk_buff *skb, int ring_offset); | ||
167 | static void slow_sane_block_output(struct net_device *dev, int count, | ||
168 | const unsigned char *buf, int start_page); | ||
169 | static void word_memcpy_tocard(unsigned long tp, const void *fp, int count); | ||
170 | static void word_memcpy_fromcard(void *tp, unsigned long fp, int count); | ||
171 | |||
172 | static enum mac8390_type __init mac8390_ident(struct nubus_dev *dev) | ||
173 | { | ||
174 | switch (dev->dr_sw) { | ||
175 | case NUBUS_DRSW_3COM: | ||
176 | switch (dev->dr_hw) { | ||
177 | case NUBUS_DRHW_APPLE_SONIC_NB: | ||
178 | case NUBUS_DRHW_APPLE_SONIC_LC: | ||
179 | case NUBUS_DRHW_SONNET: | ||
180 | return MAC8390_NONE; | ||
181 | break; | ||
182 | default: | ||
183 | return MAC8390_APPLE; | ||
184 | break; | ||
185 | } | ||
186 | break; | ||
187 | |||
188 | case NUBUS_DRSW_APPLE: | ||
189 | switch (dev->dr_hw) { | ||
190 | case NUBUS_DRHW_ASANTE_LC: | ||
191 | return MAC8390_NONE; | ||
192 | break; | ||
193 | case NUBUS_DRHW_CABLETRON: | ||
194 | return MAC8390_CABLETRON; | ||
195 | break; | ||
196 | default: | ||
197 | return MAC8390_APPLE; | ||
198 | break; | ||
199 | } | ||
200 | break; | ||
201 | |||
202 | case NUBUS_DRSW_ASANTE: | ||
203 | return MAC8390_ASANTE; | ||
204 | break; | ||
205 | |||
206 | case NUBUS_DRSW_TECHWORKS: | ||
207 | case NUBUS_DRSW_DAYNA2: | ||
208 | case NUBUS_DRSW_DAYNA_LC: | ||
209 | if (dev->dr_hw == NUBUS_DRHW_CABLETRON) | ||
210 | return MAC8390_CABLETRON; | ||
211 | else | ||
212 | return MAC8390_APPLE; | ||
213 | break; | ||
214 | |||
215 | case NUBUS_DRSW_FARALLON: | ||
216 | return MAC8390_FARALLON; | ||
217 | break; | ||
218 | |||
219 | case NUBUS_DRSW_KINETICS: | ||
220 | switch (dev->dr_hw) { | ||
221 | case NUBUS_DRHW_INTERLAN: | ||
222 | return MAC8390_INTERLAN; | ||
223 | break; | ||
224 | default: | ||
225 | return MAC8390_KINETICS; | ||
226 | break; | ||
227 | } | ||
228 | break; | ||
229 | |||
230 | case NUBUS_DRSW_DAYNA: | ||
231 | /* | ||
232 | * These correspond to Dayna Sonic cards | ||
233 | * which use the macsonic driver | ||
234 | */ | ||
235 | if (dev->dr_hw == NUBUS_DRHW_SMC9194 || | ||
236 | dev->dr_hw == NUBUS_DRHW_INTERLAN) | ||
237 | return MAC8390_NONE; | ||
238 | else | ||
239 | return MAC8390_DAYNA; | ||
240 | break; | ||
241 | } | ||
242 | return MAC8390_NONE; | ||
243 | } | ||
244 | |||
245 | static enum mac8390_access __init mac8390_testio(volatile unsigned long membase) | ||
246 | { | ||
247 | unsigned long outdata = 0xA5A0B5B0; | ||
248 | unsigned long indata = 0x00000000; | ||
249 | /* Try writing 32 bits */ | ||
250 | memcpy_toio(membase, &outdata, 4); | ||
251 | /* Now compare them */ | ||
252 | if (memcmp_withio(&outdata, membase, 4) == 0) | ||
253 | return ACCESS_32; | ||
254 | /* Write 16 bit output */ | ||
255 | word_memcpy_tocard(membase, &outdata, 4); | ||
256 | /* Now read it back */ | ||
257 | word_memcpy_fromcard(&indata, membase, 4); | ||
258 | if (outdata == indata) | ||
259 | return ACCESS_16; | ||
260 | return ACCESS_UNKNOWN; | ||
261 | } | ||
262 | |||
263 | static int __init mac8390_memsize(unsigned long membase) | ||
264 | { | ||
265 | unsigned long flags; | ||
266 | int i, j; | ||
267 | |||
268 | local_irq_save(flags); | ||
269 | /* Check up to 32K in 4K increments */ | ||
270 | for (i = 0; i < 8; i++) { | ||
271 | volatile unsigned short *m = (unsigned short *)(membase + (i * 0x1000)); | ||
272 | |||
273 | /* Unwriteable - we have a fully decoded card and the | ||
274 | RAM end located */ | ||
275 | if (hwreg_present(m) == 0) | ||
276 | break; | ||
277 | |||
278 | /* write a distinctive byte */ | ||
279 | *m = 0xA5A0 | i; | ||
280 | /* check that we read back what we wrote */ | ||
281 | if (*m != (0xA5A0 | i)) | ||
282 | break; | ||
283 | |||
284 | /* check for partial decode and wrap */ | ||
285 | for (j = 0; j < i; j++) { | ||
286 | volatile unsigned short *p = (unsigned short *)(membase + (j * 0x1000)); | ||
287 | if (*p != (0xA5A0 | j)) | ||
288 | break; | ||
289 | } | ||
290 | } | ||
291 | local_irq_restore(flags); | ||
292 | /* | ||
293 | * in any case, we stopped once we tried one block too many, | ||
294 | * or once we reached 32K | ||
295 | */ | ||
296 | return i * 0x1000; | ||
297 | } | ||
298 | |||
299 | static bool __init mac8390_init(struct net_device *dev, struct nubus_dev *ndev, | ||
300 | enum mac8390_type cardtype) | ||
301 | { | ||
302 | struct nubus_dir dir; | ||
303 | struct nubus_dirent ent; | ||
304 | int offset; | ||
305 | volatile unsigned short *i; | ||
306 | |||
307 | printk_once(KERN_INFO pr_fmt("%s"), version); | ||
308 | |||
309 | dev->irq = SLOT2IRQ(ndev->board->slot); | ||
310 | /* This is getting to be a habit */ | ||
311 | dev->base_addr = (ndev->board->slot_addr | | ||
312 | ((ndev->board->slot & 0xf) << 20)); | ||
313 | |||
314 | /* | ||
315 | * Get some Nubus info - we will trust the card's idea | ||
316 | * of where its memory and registers are. | ||
317 | */ | ||
318 | |||
319 | if (nubus_get_func_dir(ndev, &dir) == -1) { | ||
320 | pr_err("%s: Unable to get Nubus functional directory for slot %X!\n", | ||
321 | dev->name, ndev->board->slot); | ||
322 | return false; | ||
323 | } | ||
324 | |||
325 | /* Get the MAC address */ | ||
326 | if (nubus_find_rsrc(&dir, NUBUS_RESID_MAC_ADDRESS, &ent) == -1) { | ||
327 | pr_info("%s: Couldn't get MAC address!\n", dev->name); | ||
328 | return false; | ||
329 | } | ||
330 | |||
331 | nubus_get_rsrc_mem(dev->dev_addr, &ent, 6); | ||
332 | |||
333 | if (useresources[cardtype] == 1) { | ||
334 | nubus_rewinddir(&dir); | ||
335 | if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_BASEOS, | ||
336 | &ent) == -1) { | ||
337 | pr_err("%s: Memory offset resource for slot %X not found!\n", | ||
338 | dev->name, ndev->board->slot); | ||
339 | return false; | ||
340 | } | ||
341 | nubus_get_rsrc_mem(&offset, &ent, 4); | ||
342 | dev->mem_start = dev->base_addr + offset; | ||
343 | /* yes, this is how the Apple driver does it */ | ||
344 | dev->base_addr = dev->mem_start + 0x10000; | ||
345 | nubus_rewinddir(&dir); | ||
346 | if (nubus_find_rsrc(&dir, NUBUS_RESID_MINOR_LENGTH, | ||
347 | &ent) == -1) { | ||
348 | pr_info("%s: Memory length resource for slot %X not found, probing\n", | ||
349 | dev->name, ndev->board->slot); | ||
350 | offset = mac8390_memsize(dev->mem_start); | ||
351 | } else { | ||
352 | nubus_get_rsrc_mem(&offset, &ent, 4); | ||
353 | } | ||
354 | dev->mem_end = dev->mem_start + offset; | ||
355 | } else { | ||
356 | switch (cardtype) { | ||
357 | case MAC8390_KINETICS: | ||
358 | case MAC8390_DAYNA: /* it's the same */ | ||
359 | dev->base_addr = (int)(ndev->board->slot_addr + | ||
360 | DAYNA_8390_BASE); | ||
361 | dev->mem_start = (int)(ndev->board->slot_addr + | ||
362 | DAYNA_8390_MEM); | ||
363 | dev->mem_end = dev->mem_start + | ||
364 | mac8390_memsize(dev->mem_start); | ||
365 | break; | ||
366 | case MAC8390_INTERLAN: | ||
367 | dev->base_addr = (int)(ndev->board->slot_addr + | ||
368 | INTERLAN_8390_BASE); | ||
369 | dev->mem_start = (int)(ndev->board->slot_addr + | ||
370 | INTERLAN_8390_MEM); | ||
371 | dev->mem_end = dev->mem_start + | ||
372 | mac8390_memsize(dev->mem_start); | ||
373 | break; | ||
374 | case MAC8390_CABLETRON: | ||
375 | dev->base_addr = (int)(ndev->board->slot_addr + | ||
376 | CABLETRON_8390_BASE); | ||
377 | dev->mem_start = (int)(ndev->board->slot_addr + | ||
378 | CABLETRON_8390_MEM); | ||
379 | /* The base address is unreadable if 0x00 | ||
380 | * has been written to the command register | ||
381 | * Reset the chip by writing E8390_NODMA + | ||
382 | * E8390_PAGE0 + E8390_STOP just to be | ||
383 | * sure | ||
384 | */ | ||
385 | i = (void *)dev->base_addr; | ||
386 | *i = 0x21; | ||
387 | dev->mem_end = dev->mem_start + | ||
388 | mac8390_memsize(dev->mem_start); | ||
389 | break; | ||
390 | |||
391 | default: | ||
392 | pr_err("Card type %s is unsupported, sorry\n", | ||
393 | ndev->board->name); | ||
394 | return false; | ||
395 | } | ||
396 | } | ||
397 | |||
398 | return true; | ||
399 | } | ||
400 | |||
401 | struct net_device * __init mac8390_probe(int unit) | ||
402 | { | ||
403 | struct net_device *dev; | ||
404 | struct nubus_dev *ndev = NULL; | ||
405 | int err = -ENODEV; | ||
406 | |||
407 | static unsigned int slots; | ||
408 | |||
409 | enum mac8390_type cardtype; | ||
410 | |||
411 | /* probably should check for Nubus instead */ | ||
412 | |||
413 | if (!MACH_IS_MAC) | ||
414 | return ERR_PTR(-ENODEV); | ||
415 | |||
416 | dev = ____alloc_ei_netdev(0); | ||
417 | if (!dev) | ||
418 | return ERR_PTR(-ENOMEM); | ||
419 | |||
420 | if (unit >= 0) | ||
421 | sprintf(dev->name, "eth%d", unit); | ||
422 | |||
423 | while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, NUBUS_TYPE_ETHERNET, | ||
424 | ndev))) { | ||
425 | /* Have we seen it already? */ | ||
426 | if (slots & (1 << ndev->board->slot)) | ||
427 | continue; | ||
428 | slots |= 1 << ndev->board->slot; | ||
429 | |||
430 | cardtype = mac8390_ident(ndev); | ||
431 | if (cardtype == MAC8390_NONE) | ||
432 | continue; | ||
433 | |||
434 | if (!mac8390_init(dev, ndev, cardtype)) | ||
435 | continue; | ||
436 | |||
437 | /* Do the nasty 8390 stuff */ | ||
438 | if (!mac8390_initdev(dev, ndev, cardtype)) | ||
439 | break; | ||
440 | } | ||
441 | |||
442 | if (!ndev) | ||
443 | goto out; | ||
444 | err = register_netdev(dev); | ||
445 | if (err) | ||
446 | goto out; | ||
447 | return dev; | ||
448 | |||
449 | out: | ||
450 | free_netdev(dev); | ||
451 | return ERR_PTR(err); | ||
452 | } | ||
453 | |||
454 | #ifdef MODULE | ||
455 | MODULE_AUTHOR("David Huggins-Daines <dhd@debian.org> and others"); | ||
456 | MODULE_DESCRIPTION("Macintosh NS8390-based Nubus Ethernet driver"); | ||
457 | MODULE_LICENSE("GPL"); | ||
458 | |||
459 | /* overkill, of course */ | ||
460 | static struct net_device *dev_mac8390[15]; | ||
461 | int init_module(void) | ||
462 | { | ||
463 | int i; | ||
464 | for (i = 0; i < 15; i++) { | ||
465 | struct net_device *dev = mac8390_probe(-1); | ||
466 | if (IS_ERR(dev)) | ||
467 | break; | ||
468 | dev_mac890[i] = dev; | ||
469 | } | ||
470 | if (!i) { | ||
471 | pr_notice("No useable cards found, driver NOT installed.\n"); | ||
472 | return -ENODEV; | ||
473 | } | ||
474 | return 0; | ||
475 | } | ||
476 | |||
477 | void cleanup_module(void) | ||
478 | { | ||
479 | int i; | ||
480 | for (i = 0; i < 15; i++) { | ||
481 | struct net_device *dev = dev_mac890[i]; | ||
482 | if (dev) { | ||
483 | unregister_netdev(dev); | ||
484 | free_netdev(dev); | ||
485 | } | ||
486 | } | ||
487 | } | ||
488 | |||
489 | #endif /* MODULE */ | ||
490 | |||
491 | static const struct net_device_ops mac8390_netdev_ops = { | ||
492 | .ndo_open = mac8390_open, | ||
493 | .ndo_stop = mac8390_close, | ||
494 | .ndo_start_xmit = __ei_start_xmit, | ||
495 | .ndo_tx_timeout = __ei_tx_timeout, | ||
496 | .ndo_get_stats = __ei_get_stats, | ||
497 | .ndo_set_multicast_list = __ei_set_multicast_list, | ||
498 | .ndo_validate_addr = eth_validate_addr, | ||
499 | .ndo_set_mac_address = eth_mac_addr, | ||
500 | .ndo_change_mtu = eth_change_mtu, | ||
501 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
502 | .ndo_poll_controller = __ei_poll, | ||
503 | #endif | ||
504 | }; | ||
505 | |||
506 | static int __init mac8390_initdev(struct net_device *dev, | ||
507 | struct nubus_dev *ndev, | ||
508 | enum mac8390_type type) | ||
509 | { | ||
510 | static u32 fwrd4_offsets[16] = { | ||
511 | 0, 4, 8, 12, | ||
512 | 16, 20, 24, 28, | ||
513 | 32, 36, 40, 44, | ||
514 | 48, 52, 56, 60 | ||
515 | }; | ||
516 | static u32 back4_offsets[16] = { | ||
517 | 60, 56, 52, 48, | ||
518 | 44, 40, 36, 32, | ||
519 | 28, 24, 20, 16, | ||
520 | 12, 8, 4, 0 | ||
521 | }; | ||
522 | static u32 fwrd2_offsets[16] = { | ||
523 | 0, 2, 4, 6, | ||
524 | 8, 10, 12, 14, | ||
525 | 16, 18, 20, 22, | ||
526 | 24, 26, 28, 30 | ||
527 | }; | ||
528 | |||
529 | int access_bitmode = 0; | ||
530 | |||
531 | /* Now fill in our stuff */ | ||
532 | dev->netdev_ops = &mac8390_netdev_ops; | ||
533 | |||
534 | /* GAR, ei_status is actually a macro even though it looks global */ | ||
535 | ei_status.name = cardname[type]; | ||
536 | ei_status.word16 = word16[type]; | ||
537 | |||
538 | /* Cabletron's TX/RX buffers are backwards */ | ||
539 | if (type == MAC8390_CABLETRON) { | ||
540 | ei_status.tx_start_page = CABLETRON_TX_START_PG; | ||
541 | ei_status.rx_start_page = CABLETRON_RX_START_PG; | ||
542 | ei_status.stop_page = CABLETRON_RX_STOP_PG; | ||
543 | ei_status.rmem_start = dev->mem_start; | ||
544 | ei_status.rmem_end = dev->mem_start + CABLETRON_RX_STOP_PG*256; | ||
545 | } else { | ||
546 | ei_status.tx_start_page = WD_START_PG; | ||
547 | ei_status.rx_start_page = WD_START_PG + TX_PAGES; | ||
548 | ei_status.stop_page = (dev->mem_end - dev->mem_start)/256; | ||
549 | ei_status.rmem_start = dev->mem_start + TX_PAGES*256; | ||
550 | ei_status.rmem_end = dev->mem_end; | ||
551 | } | ||
552 | |||
553 | /* Fill in model-specific information and functions */ | ||
554 | switch (type) { | ||
555 | case MAC8390_FARALLON: | ||
556 | case MAC8390_APPLE: | ||
557 | switch (mac8390_testio(dev->mem_start)) { | ||
558 | case ACCESS_UNKNOWN: | ||
559 | pr_err("Don't know how to access card memory!\n"); | ||
560 | return -ENODEV; | ||
561 | break; | ||
562 | |||
563 | case ACCESS_16: | ||
564 | /* 16 bit card, register map is reversed */ | ||
565 | ei_status.reset_8390 = mac8390_no_reset; | ||
566 | ei_status.block_input = slow_sane_block_input; | ||
567 | ei_status.block_output = slow_sane_block_output; | ||
568 | ei_status.get_8390_hdr = slow_sane_get_8390_hdr; | ||
569 | ei_status.reg_offset = back4_offsets; | ||
570 | break; | ||
571 | |||
572 | case ACCESS_32: | ||
573 | /* 32 bit card, register map is reversed */ | ||
574 | ei_status.reset_8390 = mac8390_no_reset; | ||
575 | ei_status.block_input = sane_block_input; | ||
576 | ei_status.block_output = sane_block_output; | ||
577 | ei_status.get_8390_hdr = sane_get_8390_hdr; | ||
578 | ei_status.reg_offset = back4_offsets; | ||
579 | access_bitmode = 1; | ||
580 | break; | ||
581 | } | ||
582 | break; | ||
583 | |||
584 | case MAC8390_ASANTE: | ||
585 | /* Some Asante cards pass the 32 bit test | ||
586 | * but overwrite system memory when run at 32 bit. | ||
587 | * so we run them all at 16 bit. | ||
588 | */ | ||
589 | ei_status.reset_8390 = mac8390_no_reset; | ||
590 | ei_status.block_input = slow_sane_block_input; | ||
591 | ei_status.block_output = slow_sane_block_output; | ||
592 | ei_status.get_8390_hdr = slow_sane_get_8390_hdr; | ||
593 | ei_status.reg_offset = back4_offsets; | ||
594 | break; | ||
595 | |||
596 | case MAC8390_CABLETRON: | ||
597 | /* 16 bit card, register map is short forward */ | ||
598 | ei_status.reset_8390 = mac8390_no_reset; | ||
599 | ei_status.block_input = slow_sane_block_input; | ||
600 | ei_status.block_output = slow_sane_block_output; | ||
601 | ei_status.get_8390_hdr = slow_sane_get_8390_hdr; | ||
602 | ei_status.reg_offset = fwrd2_offsets; | ||
603 | break; | ||
604 | |||
605 | case MAC8390_DAYNA: | ||
606 | case MAC8390_KINETICS: | ||
607 | /* 16 bit memory, register map is forward */ | ||
608 | /* dayna and similar */ | ||
609 | ei_status.reset_8390 = mac8390_no_reset; | ||
610 | ei_status.block_input = dayna_block_input; | ||
611 | ei_status.block_output = dayna_block_output; | ||
612 | ei_status.get_8390_hdr = dayna_get_8390_hdr; | ||
613 | ei_status.reg_offset = fwrd4_offsets; | ||
614 | break; | ||
615 | |||
616 | case MAC8390_INTERLAN: | ||
617 | /* 16 bit memory, register map is forward */ | ||
618 | ei_status.reset_8390 = interlan_reset; | ||
619 | ei_status.block_input = slow_sane_block_input; | ||
620 | ei_status.block_output = slow_sane_block_output; | ||
621 | ei_status.get_8390_hdr = slow_sane_get_8390_hdr; | ||
622 | ei_status.reg_offset = fwrd4_offsets; | ||
623 | break; | ||
624 | |||
625 | default: | ||
626 | pr_err("Card type %s is unsupported, sorry\n", | ||
627 | ndev->board->name); | ||
628 | return -ENODEV; | ||
629 | } | ||
630 | |||
631 | __NS8390_init(dev, 0); | ||
632 | |||
633 | /* Good, done, now spit out some messages */ | ||
634 | pr_info("%s: %s in slot %X (type %s)\n", | ||
635 | dev->name, ndev->board->name, ndev->board->slot, | ||
636 | cardname[type]); | ||
637 | pr_info("MAC %pM IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n", | ||
638 | dev->dev_addr, dev->irq, | ||
639 | (unsigned int)(dev->mem_end - dev->mem_start) >> 10, | ||
640 | dev->mem_start, access_bitmode ? 32 : 16); | ||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | static int mac8390_open(struct net_device *dev) | ||
645 | { | ||
646 | int err; | ||
647 | |||
648 | __ei_open(dev); | ||
649 | err = request_irq(dev->irq, __ei_interrupt, 0, "8390 Ethernet", dev); | ||
650 | if (err) | ||
651 | pr_err("%s: unable to get IRQ %d\n", dev->name, dev->irq); | ||
652 | return err; | ||
653 | } | ||
654 | |||
655 | static int mac8390_close(struct net_device *dev) | ||
656 | { | ||
657 | free_irq(dev->irq, dev); | ||
658 | __ei_close(dev); | ||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | static void mac8390_no_reset(struct net_device *dev) | ||
663 | { | ||
664 | ei_status.txing = 0; | ||
665 | if (ei_debug > 1) | ||
666 | pr_info("reset not supported\n"); | ||
667 | } | ||
668 | |||
669 | static void interlan_reset(struct net_device *dev) | ||
670 | { | ||
671 | unsigned char *target = nubus_slot_addr(IRQ2SLOT(dev->irq)); | ||
672 | if (ei_debug > 1) | ||
673 | pr_info("Need to reset the NS8390 t=%lu...", jiffies); | ||
674 | ei_status.txing = 0; | ||
675 | target[0xC0000] = 0; | ||
676 | if (ei_debug > 1) | ||
677 | pr_cont("reset complete\n"); | ||
678 | } | ||
679 | |||
680 | /* dayna_memcpy_fromio/dayna_memcpy_toio */ | ||
681 | /* directly from daynaport.c by Alan Cox */ | ||
682 | static void dayna_memcpy_fromcard(struct net_device *dev, void *to, int from, | ||
683 | int count) | ||
684 | { | ||
685 | volatile unsigned char *ptr; | ||
686 | unsigned char *target = to; | ||
687 | from <<= 1; /* word, skip overhead */ | ||
688 | ptr = (unsigned char *)(dev->mem_start+from); | ||
689 | /* Leading byte? */ | ||
690 | if (from & 2) { | ||
691 | *target++ = ptr[-1]; | ||
692 | ptr += 2; | ||
693 | count--; | ||
694 | } | ||
695 | while (count >= 2) { | ||
696 | *(unsigned short *)target = *(unsigned short volatile *)ptr; | ||
697 | ptr += 4; /* skip cruft */ | ||
698 | target += 2; | ||
699 | count -= 2; | ||
700 | } | ||
701 | /* Trailing byte? */ | ||
702 | if (count) | ||
703 | *target = *ptr; | ||
704 | } | ||
705 | |||
706 | static void dayna_memcpy_tocard(struct net_device *dev, int to, | ||
707 | const void *from, int count) | ||
708 | { | ||
709 | volatile unsigned short *ptr; | ||
710 | const unsigned char *src = from; | ||
711 | to <<= 1; /* word, skip overhead */ | ||
712 | ptr = (unsigned short *)(dev->mem_start+to); | ||
713 | /* Leading byte? */ | ||
714 | if (to & 2) { /* avoid a byte write (stomps on other data) */ | ||
715 | ptr[-1] = (ptr[-1]&0xFF00)|*src++; | ||
716 | ptr++; | ||
717 | count--; | ||
718 | } | ||
719 | while (count >= 2) { | ||
720 | *ptr++ = *(unsigned short *)src; /* Copy and */ | ||
721 | ptr++; /* skip cruft */ | ||
722 | src += 2; | ||
723 | count -= 2; | ||
724 | } | ||
725 | /* Trailing byte? */ | ||
726 | if (count) { | ||
727 | /* card doesn't like byte writes */ | ||
728 | *ptr = (*ptr & 0x00FF) | (*src << 8); | ||
729 | } | ||
730 | } | ||
731 | |||
732 | /* sane block input/output */ | ||
733 | static void sane_get_8390_hdr(struct net_device *dev, | ||
734 | struct e8390_pkt_hdr *hdr, int ring_page) | ||
735 | { | ||
736 | unsigned long hdr_start = (ring_page - WD_START_PG)<<8; | ||
737 | memcpy_fromio(hdr, dev->mem_start + hdr_start, 4); | ||
738 | /* Fix endianness */ | ||
739 | hdr->count = swab16(hdr->count); | ||
740 | } | ||
741 | |||
742 | static void sane_block_input(struct net_device *dev, int count, | ||
743 | struct sk_buff *skb, int ring_offset) | ||
744 | { | ||
745 | unsigned long xfer_base = ring_offset - (WD_START_PG<<8); | ||
746 | unsigned long xfer_start = xfer_base + dev->mem_start; | ||
747 | |||
748 | if (xfer_start + count > ei_status.rmem_end) { | ||
749 | /* We must wrap the input move. */ | ||
750 | int semi_count = ei_status.rmem_end - xfer_start; | ||
751 | memcpy_fromio(skb->data, dev->mem_start + xfer_base, | ||
752 | semi_count); | ||
753 | count -= semi_count; | ||
754 | memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, | ||
755 | count); | ||
756 | } else { | ||
757 | memcpy_fromio(skb->data, dev->mem_start + xfer_base, count); | ||
758 | } | ||
759 | } | ||
760 | |||
761 | static void sane_block_output(struct net_device *dev, int count, | ||
762 | const unsigned char *buf, int start_page) | ||
763 | { | ||
764 | long shmem = (start_page - WD_START_PG)<<8; | ||
765 | |||
766 | memcpy_toio(dev->mem_start + shmem, buf, count); | ||
767 | } | ||
768 | |||
769 | /* dayna block input/output */ | ||
770 | static void dayna_get_8390_hdr(struct net_device *dev, | ||
771 | struct e8390_pkt_hdr *hdr, int ring_page) | ||
772 | { | ||
773 | unsigned long hdr_start = (ring_page - WD_START_PG)<<8; | ||
774 | |||
775 | dayna_memcpy_fromcard(dev, hdr, hdr_start, 4); | ||
776 | /* Fix endianness */ | ||
777 | hdr->count = (hdr->count & 0xFF) << 8 | (hdr->count >> 8); | ||
778 | } | ||
779 | |||
780 | static void dayna_block_input(struct net_device *dev, int count, | ||
781 | struct sk_buff *skb, int ring_offset) | ||
782 | { | ||
783 | unsigned long xfer_base = ring_offset - (WD_START_PG<<8); | ||
784 | unsigned long xfer_start = xfer_base+dev->mem_start; | ||
785 | |||
786 | /* Note the offset math is done in card memory space which is word | ||
787 | per long onto our space. */ | ||
788 | |||
789 | if (xfer_start + count > ei_status.rmem_end) { | ||
790 | /* We must wrap the input move. */ | ||
791 | int semi_count = ei_status.rmem_end - xfer_start; | ||
792 | dayna_memcpy_fromcard(dev, skb->data, xfer_base, semi_count); | ||
793 | count -= semi_count; | ||
794 | dayna_memcpy_fromcard(dev, skb->data + semi_count, | ||
795 | ei_status.rmem_start - dev->mem_start, | ||
796 | count); | ||
797 | } else { | ||
798 | dayna_memcpy_fromcard(dev, skb->data, xfer_base, count); | ||
799 | } | ||
800 | } | ||
801 | |||
802 | static void dayna_block_output(struct net_device *dev, int count, | ||
803 | const unsigned char *buf, | ||
804 | int start_page) | ||
805 | { | ||
806 | long shmem = (start_page - WD_START_PG)<<8; | ||
807 | |||
808 | dayna_memcpy_tocard(dev, shmem, buf, count); | ||
809 | } | ||
810 | |||
811 | /* Cabletron block I/O */ | ||
812 | static void slow_sane_get_8390_hdr(struct net_device *dev, | ||
813 | struct e8390_pkt_hdr *hdr, | ||
814 | int ring_page) | ||
815 | { | ||
816 | unsigned long hdr_start = (ring_page - WD_START_PG)<<8; | ||
817 | word_memcpy_fromcard(hdr, dev->mem_start + hdr_start, 4); | ||
818 | /* Register endianism - fix here rather than 8390.c */ | ||
819 | hdr->count = (hdr->count&0xFF)<<8|(hdr->count>>8); | ||
820 | } | ||
821 | |||
822 | static void slow_sane_block_input(struct net_device *dev, int count, | ||
823 | struct sk_buff *skb, int ring_offset) | ||
824 | { | ||
825 | unsigned long xfer_base = ring_offset - (WD_START_PG<<8); | ||
826 | unsigned long xfer_start = xfer_base+dev->mem_start; | ||
827 | |||
828 | if (xfer_start + count > ei_status.rmem_end) { | ||
829 | /* We must wrap the input move. */ | ||
830 | int semi_count = ei_status.rmem_end - xfer_start; | ||
831 | word_memcpy_fromcard(skb->data, dev->mem_start + xfer_base, | ||
832 | semi_count); | ||
833 | count -= semi_count; | ||
834 | word_memcpy_fromcard(skb->data + semi_count, | ||
835 | ei_status.rmem_start, count); | ||
836 | } else { | ||
837 | word_memcpy_fromcard(skb->data, dev->mem_start + xfer_base, | ||
838 | count); | ||
839 | } | ||
840 | } | ||
841 | |||
842 | static void slow_sane_block_output(struct net_device *dev, int count, | ||
843 | const unsigned char *buf, int start_page) | ||
844 | { | ||
845 | long shmem = (start_page - WD_START_PG)<<8; | ||
846 | |||
847 | word_memcpy_tocard(dev->mem_start + shmem, buf, count); | ||
848 | } | ||
849 | |||
850 | static void word_memcpy_tocard(unsigned long tp, const void *fp, int count) | ||
851 | { | ||
852 | volatile unsigned short *to = (void *)tp; | ||
853 | const unsigned short *from = fp; | ||
854 | |||
855 | count++; | ||
856 | count /= 2; | ||
857 | |||
858 | while (count--) | ||
859 | *to++ = *from++; | ||
860 | } | ||
861 | |||
862 | static void word_memcpy_fromcard(void *tp, unsigned long fp, int count) | ||
863 | { | ||
864 | unsigned short *to = tp; | ||
865 | const volatile unsigned short *from = (const void *)fp; | ||
866 | |||
867 | count++; | ||
868 | count /= 2; | ||
869 | |||
870 | while (count--) | ||
871 | *to++ = *from++; | ||
872 | } | ||
873 | |||
874 | |||
diff --git a/drivers/net/ethernet/8390/ne-h8300.c b/drivers/net/ethernet/8390/ne-h8300.c new file mode 100644 index 000000000000..7298a34bc795 --- /dev/null +++ b/drivers/net/ethernet/8390/ne-h8300.c | |||
@@ -0,0 +1,685 @@ | |||
1 | /* ne-h8300.c: A NE2000 clone on H8/300 driver for linux. */ | ||
2 | /* | ||
3 | original ne.c | ||
4 | Written 1992-94 by Donald Becker. | ||
5 | |||
6 | Copyright 1993 United States Government as represented by the | ||
7 | Director, National Security Agency. | ||
8 | |||
9 | This software may be used and distributed according to the terms | ||
10 | of the GNU General Public License, incorporated herein by reference. | ||
11 | |||
12 | The author may be reached as becker@scyld.com, or C/O | ||
13 | Scyld Computing Corporation, 410 Severn Ave., Suite 210, Annapolis MD 21403 | ||
14 | |||
15 | H8/300 modified | ||
16 | Yoshinori Sato <ysato@users.sourceforge.jp> | ||
17 | */ | ||
18 | |||
19 | static const char version1[] = | ||
20 | "ne-h8300.c:v1.00 2004/04/11 ysato\n"; | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/delay.h> | ||
28 | #include <linux/netdevice.h> | ||
29 | #include <linux/etherdevice.h> | ||
30 | #include <linux/jiffies.h> | ||
31 | |||
32 | #include <asm/system.h> | ||
33 | #include <asm/io.h> | ||
34 | #include <asm/irq.h> | ||
35 | |||
36 | #define EI_SHIFT(x) (ei_local->reg_offset[x]) | ||
37 | |||
38 | #include "8390.h" | ||
39 | |||
40 | #define DRV_NAME "ne-h8300" | ||
41 | |||
42 | /* Some defines that people can play with if so inclined. */ | ||
43 | |||
44 | /* Do we perform extra sanity checks on stuff ? */ | ||
45 | /* #define NE_SANITY_CHECK */ | ||
46 | |||
47 | /* Do we implement the read before write bugfix ? */ | ||
48 | /* #define NE_RW_BUGFIX */ | ||
49 | |||
50 | /* Do we have a non std. amount of memory? (in units of 256 byte pages) */ | ||
51 | /* #define PACKETBUF_MEMSIZE 0x40 */ | ||
52 | |||
53 | /* A zero-terminated list of I/O addresses to be probed at boot. */ | ||
54 | |||
55 | /* ---- No user-serviceable parts below ---- */ | ||
56 | |||
57 | static const char version[] = | ||
58 | "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; | ||
59 | |||
60 | #include "lib8390.c" | ||
61 | |||
62 | #define NE_BASE (dev->base_addr) | ||
63 | #define NE_CMD 0x00 | ||
64 | #define NE_DATAPORT (ei_status.word16?0x20:0x10) /* NatSemi-defined port window offset. */ | ||
65 | #define NE_RESET (ei_status.word16?0x3f:0x1f) /* Issue a read to reset, a write to clear. */ | ||
66 | #define NE_IO_EXTENT (ei_status.word16?0x40:0x20) | ||
67 | |||
68 | #define NESM_START_PG 0x40 /* First page of TX buffer */ | ||
69 | #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
70 | |||
71 | static int ne_probe1(struct net_device *dev, int ioaddr); | ||
72 | |||
73 | static int ne_open(struct net_device *dev); | ||
74 | static int ne_close(struct net_device *dev); | ||
75 | |||
76 | static void ne_reset_8390(struct net_device *dev); | ||
77 | static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
78 | int ring_page); | ||
79 | static void ne_block_input(struct net_device *dev, int count, | ||
80 | struct sk_buff *skb, int ring_offset); | ||
81 | static void ne_block_output(struct net_device *dev, const int count, | ||
82 | const unsigned char *buf, const int start_page); | ||
83 | |||
84 | |||
85 | static u32 reg_offset[16]; | ||
86 | |||
87 | static int __init init_reg_offset(struct net_device *dev,unsigned long base_addr) | ||
88 | { | ||
89 | struct ei_device *ei_local = netdev_priv(dev); | ||
90 | int i; | ||
91 | unsigned char bus_width; | ||
92 | |||
93 | bus_width = *(volatile unsigned char *)ABWCR; | ||
94 | bus_width &= 1 << ((base_addr >> 21) & 7); | ||
95 | |||
96 | for (i = 0; i < ARRAY_SIZE(reg_offset); i++) | ||
97 | if (bus_width == 0) | ||
98 | reg_offset[i] = i * 2 + 1; | ||
99 | else | ||
100 | reg_offset[i] = i; | ||
101 | |||
102 | ei_local->reg_offset = reg_offset; | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static int __initdata h8300_ne_count = 0; | ||
107 | #ifdef CONFIG_H8300H_H8MAX | ||
108 | static unsigned long __initdata h8300_ne_base[] = { 0x800600 }; | ||
109 | static int h8300_ne_irq[] = {EXT_IRQ4}; | ||
110 | #endif | ||
111 | #ifdef CONFIG_H8300H_AKI3068NET | ||
112 | static unsigned long __initdata h8300_ne_base[] = { 0x200000 }; | ||
113 | static int h8300_ne_irq[] = {EXT_IRQ5}; | ||
114 | #endif | ||
115 | |||
116 | static inline int init_dev(struct net_device *dev) | ||
117 | { | ||
118 | if (h8300_ne_count < ARRAY_SIZE(h8300_ne_base)) { | ||
119 | dev->base_addr = h8300_ne_base[h8300_ne_count]; | ||
120 | dev->irq = h8300_ne_irq[h8300_ne_count]; | ||
121 | h8300_ne_count++; | ||
122 | return 0; | ||
123 | } else | ||
124 | return -ENODEV; | ||
125 | } | ||
126 | |||
127 | /* Probe for various non-shared-memory ethercards. | ||
128 | |||
129 | NEx000-clone boards have a Station Address PROM (SAPROM) in the packet | ||
130 | buffer memory space. NE2000 clones have 0x57,0x57 in bytes 0x0e,0x0f of | ||
131 | the SAPROM, while other supposed NE2000 clones must be detected by their | ||
132 | SA prefix. | ||
133 | |||
134 | Reading the SAPROM from a word-wide card with the 8390 set in byte-wide | ||
135 | mode results in doubled values, which can be detected and compensated for. | ||
136 | |||
137 | The probe is also responsible for initializing the card and filling | ||
138 | in the 'dev' and 'ei_status' structures. | ||
139 | |||
140 | We use the minimum memory size for some ethercard product lines, iff we can't | ||
141 | distinguish models. You can increase the packet buffer size by setting | ||
142 | PACKETBUF_MEMSIZE. Reported Cabletron packet buffer locations are: | ||
143 | E1010 starts at 0x100 and ends at 0x2000. | ||
144 | E1010-x starts at 0x100 and ends at 0x8000. ("-x" means "more memory") | ||
145 | E2010 starts at 0x100 and ends at 0x4000. | ||
146 | E2010-x starts at 0x100 and ends at 0xffff. */ | ||
147 | |||
148 | static int __init do_ne_probe(struct net_device *dev) | ||
149 | { | ||
150 | unsigned int base_addr = dev->base_addr; | ||
151 | |||
152 | /* First check any supplied i/o locations. User knows best. <cough> */ | ||
153 | if (base_addr > 0x1ff) /* Check a single specified location. */ | ||
154 | return ne_probe1(dev, base_addr); | ||
155 | else if (base_addr != 0) /* Don't probe at all. */ | ||
156 | return -ENXIO; | ||
157 | |||
158 | return -ENODEV; | ||
159 | } | ||
160 | |||
161 | static void cleanup_card(struct net_device *dev) | ||
162 | { | ||
163 | free_irq(dev->irq, dev); | ||
164 | release_region(dev->base_addr, NE_IO_EXTENT); | ||
165 | } | ||
166 | |||
167 | #ifndef MODULE | ||
168 | struct net_device * __init ne_probe(int unit) | ||
169 | { | ||
170 | struct net_device *dev = ____alloc_ei_netdev(0); | ||
171 | int err; | ||
172 | |||
173 | if (!dev) | ||
174 | return ERR_PTR(-ENOMEM); | ||
175 | |||
176 | if (init_dev(dev)) | ||
177 | return ERR_PTR(-ENODEV); | ||
178 | |||
179 | sprintf(dev->name, "eth%d", unit); | ||
180 | netdev_boot_setup_check(dev); | ||
181 | |||
182 | err = init_reg_offset(dev, dev->base_addr); | ||
183 | if (err) | ||
184 | goto out; | ||
185 | |||
186 | err = do_ne_probe(dev); | ||
187 | if (err) | ||
188 | goto out; | ||
189 | return dev; | ||
190 | out: | ||
191 | free_netdev(dev); | ||
192 | return ERR_PTR(err); | ||
193 | } | ||
194 | #endif | ||
195 | |||
196 | static const struct net_device_ops ne_netdev_ops = { | ||
197 | .ndo_open = ne_open, | ||
198 | .ndo_stop = ne_close, | ||
199 | |||
200 | .ndo_start_xmit = __ei_start_xmit, | ||
201 | .ndo_tx_timeout = __ei_tx_timeout, | ||
202 | .ndo_get_stats = __ei_get_stats, | ||
203 | .ndo_set_multicast_list = __ei_set_multicast_list, | ||
204 | .ndo_validate_addr = eth_validate_addr, | ||
205 | .ndo_set_mac_address = eth_mac_addr, | ||
206 | .ndo_change_mtu = eth_change_mtu, | ||
207 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
208 | .ndo_poll_controller = __ei_poll, | ||
209 | #endif | ||
210 | }; | ||
211 | |||
212 | static int __init ne_probe1(struct net_device *dev, int ioaddr) | ||
213 | { | ||
214 | int i; | ||
215 | unsigned char SA_prom[16]; | ||
216 | int wordlength = 2; | ||
217 | const char *name = NULL; | ||
218 | int start_page, stop_page; | ||
219 | int reg0, ret; | ||
220 | static unsigned version_printed; | ||
221 | struct ei_device *ei_local = netdev_priv(dev); | ||
222 | unsigned char bus_width; | ||
223 | |||
224 | if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME)) | ||
225 | return -EBUSY; | ||
226 | |||
227 | reg0 = inb_p(ioaddr); | ||
228 | if (reg0 == 0xFF) { | ||
229 | ret = -ENODEV; | ||
230 | goto err_out; | ||
231 | } | ||
232 | |||
233 | /* Do a preliminary verification that we have a 8390. */ | ||
234 | { | ||
235 | int regd; | ||
236 | outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); | ||
237 | regd = inb_p(ioaddr + EI_SHIFT(0x0d)); | ||
238 | outb_p(0xff, ioaddr + EI_SHIFT(0x0d)); | ||
239 | outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD); | ||
240 | inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ | ||
241 | if (inb_p(ioaddr + EN0_COUNTER0) != 0) { | ||
242 | outb_p(reg0, ioaddr + EI_SHIFT(0)); | ||
243 | outb_p(regd, ioaddr + EI_SHIFT(0x0d)); /* Restore the old values. */ | ||
244 | ret = -ENODEV; | ||
245 | goto err_out; | ||
246 | } | ||
247 | } | ||
248 | |||
249 | if (ei_debug && version_printed++ == 0) | ||
250 | printk(KERN_INFO "%s", version1); | ||
251 | |||
252 | printk(KERN_INFO "NE*000 ethercard probe at %08x:", ioaddr); | ||
253 | |||
254 | /* Read the 16 bytes of station address PROM. | ||
255 | We must first initialize registers, similar to NS8390_init(eifdev, 0). | ||
256 | We can't reliably read the SAPROM address without this. | ||
257 | (I learned the hard way!). */ | ||
258 | { | ||
259 | struct {unsigned char value, offset; } program_seq[] = | ||
260 | { | ||
261 | {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ | ||
262 | {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ | ||
263 | {0x00, EN0_RCNTLO}, /* Clear the count regs. */ | ||
264 | {0x00, EN0_RCNTHI}, | ||
265 | {0x00, EN0_IMR}, /* Mask completion irq. */ | ||
266 | {0xFF, EN0_ISR}, | ||
267 | {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ | ||
268 | {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ | ||
269 | {32, EN0_RCNTLO}, | ||
270 | {0x00, EN0_RCNTHI}, | ||
271 | {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ | ||
272 | {0x00, EN0_RSARHI}, | ||
273 | {E8390_RREAD+E8390_START, E8390_CMD}, | ||
274 | }; | ||
275 | |||
276 | for (i = 0; i < ARRAY_SIZE(program_seq); i++) | ||
277 | outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); | ||
278 | |||
279 | } | ||
280 | bus_width = *(volatile unsigned char *)ABWCR; | ||
281 | bus_width &= 1 << ((ioaddr >> 21) & 7); | ||
282 | ei_status.word16 = (bus_width == 0); /* temporary setting */ | ||
283 | for(i = 0; i < 16 /*sizeof(SA_prom)*/; i++) { | ||
284 | SA_prom[i] = inb_p(ioaddr + NE_DATAPORT); | ||
285 | inb_p(ioaddr + NE_DATAPORT); /* dummy read */ | ||
286 | } | ||
287 | |||
288 | start_page = NESM_START_PG; | ||
289 | stop_page = NESM_STOP_PG; | ||
290 | |||
291 | if (bus_width) | ||
292 | wordlength = 1; | ||
293 | else | ||
294 | outb_p(0x49, ioaddr + EN0_DCFG); | ||
295 | |||
296 | /* Set up the rest of the parameters. */ | ||
297 | name = (wordlength == 2) ? "NE2000" : "NE1000"; | ||
298 | |||
299 | if (! dev->irq) { | ||
300 | printk(" failed to detect IRQ line.\n"); | ||
301 | ret = -EAGAIN; | ||
302 | goto err_out; | ||
303 | } | ||
304 | |||
305 | /* Snarf the interrupt now. There's no point in waiting since we cannot | ||
306 | share and the board will usually be enabled. */ | ||
307 | ret = request_irq(dev->irq, __ei_interrupt, 0, name, dev); | ||
308 | if (ret) { | ||
309 | printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret); | ||
310 | goto err_out; | ||
311 | } | ||
312 | |||
313 | dev->base_addr = ioaddr; | ||
314 | |||
315 | for(i = 0; i < ETHER_ADDR_LEN; i++) | ||
316 | dev->dev_addr[i] = SA_prom[i]; | ||
317 | printk(" %pM\n", dev->dev_addr); | ||
318 | |||
319 | printk("%s: %s found at %#x, using IRQ %d.\n", | ||
320 | dev->name, name, ioaddr, dev->irq); | ||
321 | |||
322 | ei_status.name = name; | ||
323 | ei_status.tx_start_page = start_page; | ||
324 | ei_status.stop_page = stop_page; | ||
325 | ei_status.word16 = (wordlength == 2); | ||
326 | |||
327 | ei_status.rx_start_page = start_page + TX_PAGES; | ||
328 | #ifdef PACKETBUF_MEMSIZE | ||
329 | /* Allow the packet buffer size to be overridden by know-it-alls. */ | ||
330 | ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; | ||
331 | #endif | ||
332 | |||
333 | ei_status.reset_8390 = &ne_reset_8390; | ||
334 | ei_status.block_input = &ne_block_input; | ||
335 | ei_status.block_output = &ne_block_output; | ||
336 | ei_status.get_8390_hdr = &ne_get_8390_hdr; | ||
337 | ei_status.priv = 0; | ||
338 | |||
339 | dev->netdev_ops = &ne_netdev_ops; | ||
340 | |||
341 | __NS8390_init(dev, 0); | ||
342 | |||
343 | ret = register_netdev(dev); | ||
344 | if (ret) | ||
345 | goto out_irq; | ||
346 | return 0; | ||
347 | out_irq: | ||
348 | free_irq(dev->irq, dev); | ||
349 | err_out: | ||
350 | release_region(ioaddr, NE_IO_EXTENT); | ||
351 | return ret; | ||
352 | } | ||
353 | |||
354 | static int ne_open(struct net_device *dev) | ||
355 | { | ||
356 | __ei_open(dev); | ||
357 | return 0; | ||
358 | } | ||
359 | |||
360 | static int ne_close(struct net_device *dev) | ||
361 | { | ||
362 | if (ei_debug > 1) | ||
363 | printk(KERN_DEBUG "%s: Shutting down ethercard.\n", dev->name); | ||
364 | __ei_close(dev); | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | /* Hard reset the card. This used to pause for the same period that a | ||
369 | 8390 reset command required, but that shouldn't be necessary. */ | ||
370 | |||
371 | static void ne_reset_8390(struct net_device *dev) | ||
372 | { | ||
373 | unsigned long reset_start_time = jiffies; | ||
374 | struct ei_device *ei_local = netdev_priv(dev); | ||
375 | |||
376 | if (ei_debug > 1) | ||
377 | printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies); | ||
378 | |||
379 | /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ | ||
380 | outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); | ||
381 | |||
382 | ei_status.txing = 0; | ||
383 | ei_status.dmaing = 0; | ||
384 | |||
385 | /* This check _should_not_ be necessary, omit eventually. */ | ||
386 | while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) | ||
387 | if (time_after(jiffies, reset_start_time + 2*HZ/100)) { | ||
388 | printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name); | ||
389 | break; | ||
390 | } | ||
391 | outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ | ||
392 | } | ||
393 | |||
394 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
395 | we don't need to be concerned with ring wrap as the header will be at | ||
396 | the start of a page, so we optimize accordingly. */ | ||
397 | |||
398 | static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
399 | { | ||
400 | struct ei_device *ei_local = netdev_priv(dev); | ||
401 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
402 | |||
403 | if (ei_status.dmaing) | ||
404 | { | ||
405 | printk(KERN_EMERG "%s: DMAing conflict in ne_get_8390_hdr " | ||
406 | "[DMAstat:%d][irqlock:%d].\n", | ||
407 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
408 | return; | ||
409 | } | ||
410 | |||
411 | ei_status.dmaing |= 0x01; | ||
412 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, NE_BASE + NE_CMD); | ||
413 | outb_p(sizeof(struct e8390_pkt_hdr), NE_BASE + EN0_RCNTLO); | ||
414 | outb_p(0, NE_BASE + EN0_RCNTHI); | ||
415 | outb_p(0, NE_BASE + EN0_RSARLO); /* On page boundary */ | ||
416 | outb_p(ring_page, NE_BASE + EN0_RSARHI); | ||
417 | outb_p(E8390_RREAD+E8390_START, NE_BASE + NE_CMD); | ||
418 | |||
419 | if (ei_status.word16) { | ||
420 | int len; | ||
421 | unsigned short *p = (unsigned short *)hdr; | ||
422 | for (len = sizeof(struct e8390_pkt_hdr)>>1; len > 0; len--) | ||
423 | *p++ = inw(NE_BASE + NE_DATAPORT); | ||
424 | } else | ||
425 | insb(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)); | ||
426 | |||
427 | outb_p(ENISR_RDC, NE_BASE + EN0_ISR); /* Ack intr. */ | ||
428 | ei_status.dmaing &= ~0x01; | ||
429 | |||
430 | le16_to_cpus(&hdr->count); | ||
431 | } | ||
432 | |||
433 | /* Block input and output, similar to the Crynwr packet driver. If you | ||
434 | are porting to a new ethercard, look at the packet driver source for hints. | ||
435 | The NEx000 doesn't share the on-board packet memory -- you have to put | ||
436 | the packet out through the "remote DMA" dataport using outb. */ | ||
437 | |||
438 | static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
439 | { | ||
440 | struct ei_device *ei_local = netdev_priv(dev); | ||
441 | #ifdef NE_SANITY_CHECK | ||
442 | int xfer_count = count; | ||
443 | #endif | ||
444 | char *buf = skb->data; | ||
445 | |||
446 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
447 | if (ei_status.dmaing) | ||
448 | { | ||
449 | printk(KERN_EMERG "%s: DMAing conflict in ne_block_input " | ||
450 | "[DMAstat:%d][irqlock:%d].\n", | ||
451 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
452 | return; | ||
453 | } | ||
454 | ei_status.dmaing |= 0x01; | ||
455 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, NE_BASE + NE_CMD); | ||
456 | outb_p(count & 0xff, NE_BASE + EN0_RCNTLO); | ||
457 | outb_p(count >> 8, NE_BASE + EN0_RCNTHI); | ||
458 | outb_p(ring_offset & 0xff, NE_BASE + EN0_RSARLO); | ||
459 | outb_p(ring_offset >> 8, NE_BASE + EN0_RSARHI); | ||
460 | outb_p(E8390_RREAD+E8390_START, NE_BASE + NE_CMD); | ||
461 | if (ei_status.word16) | ||
462 | { | ||
463 | int len; | ||
464 | unsigned short *p = (unsigned short *)buf; | ||
465 | for (len = count>>1; len > 0; len--) | ||
466 | *p++ = inw(NE_BASE + NE_DATAPORT); | ||
467 | if (count & 0x01) | ||
468 | { | ||
469 | buf[count-1] = inb(NE_BASE + NE_DATAPORT); | ||
470 | #ifdef NE_SANITY_CHECK | ||
471 | xfer_count++; | ||
472 | #endif | ||
473 | } | ||
474 | } else { | ||
475 | insb(NE_BASE + NE_DATAPORT, buf, count); | ||
476 | } | ||
477 | |||
478 | #ifdef NE_SANITY_CHECK | ||
479 | /* This was for the ALPHA version only, but enough people have | ||
480 | been encountering problems so it is still here. If you see | ||
481 | this message you either 1) have a slightly incompatible clone | ||
482 | or 2) have noise/speed problems with your bus. */ | ||
483 | |||
484 | if (ei_debug > 1) | ||
485 | { | ||
486 | /* DMA termination address check... */ | ||
487 | int addr, tries = 20; | ||
488 | do { | ||
489 | /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here | ||
490 | -- it's broken for Rx on some cards! */ | ||
491 | int high = inb_p(NE_BASE + EN0_RSARHI); | ||
492 | int low = inb_p(NE_BASE + EN0_RSARLO); | ||
493 | addr = (high << 8) + low; | ||
494 | if (((ring_offset + xfer_count) & 0xff) == low) | ||
495 | break; | ||
496 | } while (--tries > 0); | ||
497 | if (tries <= 0) | ||
498 | printk(KERN_WARNING "%s: RX transfer address mismatch," | ||
499 | "%#4.4x (expected) vs. %#4.4x (actual).\n", | ||
500 | dev->name, ring_offset + xfer_count, addr); | ||
501 | } | ||
502 | #endif | ||
503 | outb_p(ENISR_RDC, NE_BASE + EN0_ISR); /* Ack intr. */ | ||
504 | ei_status.dmaing &= ~0x01; | ||
505 | } | ||
506 | |||
507 | static void ne_block_output(struct net_device *dev, int count, | ||
508 | const unsigned char *buf, const int start_page) | ||
509 | { | ||
510 | struct ei_device *ei_local = netdev_priv(dev); | ||
511 | unsigned long dma_start; | ||
512 | #ifdef NE_SANITY_CHECK | ||
513 | int retries = 0; | ||
514 | #endif | ||
515 | |||
516 | /* Round the count up for word writes. Do we need to do this? | ||
517 | What effect will an odd byte count have on the 8390? | ||
518 | I should check someday. */ | ||
519 | |||
520 | if (ei_status.word16 && (count & 0x01)) | ||
521 | count++; | ||
522 | |||
523 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
524 | if (ei_status.dmaing) | ||
525 | { | ||
526 | printk(KERN_EMERG "%s: DMAing conflict in ne_block_output." | ||
527 | "[DMAstat:%d][irqlock:%d]\n", | ||
528 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
529 | return; | ||
530 | } | ||
531 | ei_status.dmaing |= 0x01; | ||
532 | /* We should already be in page 0, but to be safe... */ | ||
533 | outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, NE_BASE + NE_CMD); | ||
534 | |||
535 | #ifdef NE_SANITY_CHECK | ||
536 | retry: | ||
537 | #endif | ||
538 | |||
539 | #ifdef NE8390_RW_BUGFIX | ||
540 | /* Handle the read-before-write bug the same way as the | ||
541 | Crynwr packet driver -- the NatSemi method doesn't work. | ||
542 | Actually this doesn't always work either, but if you have | ||
543 | problems with your NEx000 this is better than nothing! */ | ||
544 | |||
545 | outb_p(0x42, NE_BASE + EN0_RCNTLO); | ||
546 | outb_p(0x00, NE_BASE + EN0_RCNTHI); | ||
547 | outb_p(0x42, NE_BASE + EN0_RSARLO); | ||
548 | outb_p(0x00, NE_BASE + EN0_RSARHI); | ||
549 | outb_p(E8390_RREAD+E8390_START, NE_BASE + NE_CMD); | ||
550 | /* Make certain that the dummy read has occurred. */ | ||
551 | udelay(6); | ||
552 | #endif | ||
553 | |||
554 | outb_p(ENISR_RDC, NE_BASE + EN0_ISR); | ||
555 | |||
556 | /* Now the normal output. */ | ||
557 | outb_p(count & 0xff, NE_BASE + EN0_RCNTLO); | ||
558 | outb_p(count >> 8, NE_BASE + EN0_RCNTHI); | ||
559 | outb_p(0x00, NE_BASE + EN0_RSARLO); | ||
560 | outb_p(start_page, NE_BASE + EN0_RSARHI); | ||
561 | |||
562 | outb_p(E8390_RWRITE+E8390_START, NE_BASE + NE_CMD); | ||
563 | if (ei_status.word16) { | ||
564 | int len; | ||
565 | unsigned short *p = (unsigned short *)buf; | ||
566 | for (len = count>>1; len > 0; len--) | ||
567 | outw(*p++, NE_BASE + NE_DATAPORT); | ||
568 | } else { | ||
569 | outsb(NE_BASE + NE_DATAPORT, buf, count); | ||
570 | } | ||
571 | |||
572 | dma_start = jiffies; | ||
573 | |||
574 | #ifdef NE_SANITY_CHECK | ||
575 | /* This was for the ALPHA version only, but enough people have | ||
576 | been encountering problems so it is still here. */ | ||
577 | |||
578 | if (ei_debug > 1) | ||
579 | { | ||
580 | /* DMA termination address check... */ | ||
581 | int addr, tries = 20; | ||
582 | do { | ||
583 | int high = inb_p(NE_BASE + EN0_RSARHI); | ||
584 | int low = inb_p(NE_BASE + EN0_RSARLO); | ||
585 | addr = (high << 8) + low; | ||
586 | if ((start_page << 8) + count == addr) | ||
587 | break; | ||
588 | } while (--tries > 0); | ||
589 | |||
590 | if (tries <= 0) | ||
591 | { | ||
592 | printk(KERN_WARNING "%s: Tx packet transfer address mismatch," | ||
593 | "%#4.4x (expected) vs. %#4.4x (actual).\n", | ||
594 | dev->name, (start_page << 8) + count, addr); | ||
595 | if (retries++ == 0) | ||
596 | goto retry; | ||
597 | } | ||
598 | } | ||
599 | #endif | ||
600 | |||
601 | while ((inb_p(NE_BASE + EN0_ISR) & ENISR_RDC) == 0) | ||
602 | if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ | ||
603 | printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); | ||
604 | ne_reset_8390(dev); | ||
605 | __NS8390_init(dev,1); | ||
606 | break; | ||
607 | } | ||
608 | |||
609 | outb_p(ENISR_RDC, NE_BASE + EN0_ISR); /* Ack intr. */ | ||
610 | ei_status.dmaing &= ~0x01; | ||
611 | } | ||
612 | |||
613 | |||
614 | #ifdef MODULE | ||
615 | #define MAX_NE_CARDS 1 /* Max number of NE cards per module */ | ||
616 | static struct net_device *dev_ne[MAX_NE_CARDS]; | ||
617 | static int io[MAX_NE_CARDS]; | ||
618 | static int irq[MAX_NE_CARDS]; | ||
619 | static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */ | ||
620 | |||
621 | module_param_array(io, int, NULL, 0); | ||
622 | module_param_array(irq, int, NULL, 0); | ||
623 | module_param_array(bad, int, NULL, 0); | ||
624 | MODULE_PARM_DESC(io, "I/O base address(es)"); | ||
625 | MODULE_PARM_DESC(irq, "IRQ number(s)"); | ||
626 | MODULE_DESCRIPTION("H8/300 NE2000 Ethernet driver"); | ||
627 | MODULE_LICENSE("GPL"); | ||
628 | |||
629 | /* This is set up so that no ISA autoprobe takes place. We can't guarantee | ||
630 | that the ne2k probe is the last 8390 based probe to take place (as it | ||
631 | is at boot) and so the probe will get confused by any other 8390 cards. | ||
632 | ISA device autoprobes on a running machine are not recommended anyway. */ | ||
633 | |||
634 | int init_module(void) | ||
635 | { | ||
636 | int this_dev, found = 0; | ||
637 | int err; | ||
638 | |||
639 | for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { | ||
640 | struct net_device *dev = ____alloc_ei_netdev(0); | ||
641 | if (!dev) | ||
642 | break; | ||
643 | if (io[this_dev]) { | ||
644 | dev->irq = irq[this_dev]; | ||
645 | dev->mem_end = bad[this_dev]; | ||
646 | dev->base_addr = io[this_dev]; | ||
647 | } else { | ||
648 | dev->base_addr = h8300_ne_base[this_dev]; | ||
649 | dev->irq = h8300_ne_irq[this_dev]; | ||
650 | } | ||
651 | err = init_reg_offset(dev, dev->base_addr); | ||
652 | if (!err) { | ||
653 | if (do_ne_probe(dev) == 0) { | ||
654 | dev_ne[found++] = dev; | ||
655 | continue; | ||
656 | } | ||
657 | } | ||
658 | free_netdev(dev); | ||
659 | if (found) | ||
660 | break; | ||
661 | if (io[this_dev] != 0) | ||
662 | printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", dev->base_addr); | ||
663 | else | ||
664 | printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n"); | ||
665 | return -ENXIO; | ||
666 | } | ||
667 | if (found) | ||
668 | return 0; | ||
669 | return -ENODEV; | ||
670 | } | ||
671 | |||
672 | void cleanup_module(void) | ||
673 | { | ||
674 | int this_dev; | ||
675 | |||
676 | for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { | ||
677 | struct net_device *dev = dev_ne[this_dev]; | ||
678 | if (dev) { | ||
679 | unregister_netdev(dev); | ||
680 | cleanup_card(dev); | ||
681 | free_netdev(dev); | ||
682 | } | ||
683 | } | ||
684 | } | ||
685 | #endif /* MODULE */ | ||
diff --git a/drivers/net/ethernet/8390/ne.c b/drivers/net/ethernet/8390/ne.c new file mode 100644 index 000000000000..1063093b3afc --- /dev/null +++ b/drivers/net/ethernet/8390/ne.c | |||
@@ -0,0 +1,1008 @@ | |||
1 | /* ne.c: A general non-shared-memory NS8390 ethernet driver for linux. */ | ||
2 | /* | ||
3 | Written 1992-94 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, 410 Severn Ave., Suite 210, Annapolis MD 21403 | ||
13 | |||
14 | This driver should work with many programmed-I/O 8390-based ethernet | ||
15 | boards. Currently it supports the NE1000, NE2000, many clones, | ||
16 | and some Cabletron products. | ||
17 | |||
18 | Changelog: | ||
19 | |||
20 | Paul Gortmaker : use ENISR_RDC to monitor Tx PIO uploads, made | ||
21 | sanity checks and bad clone support optional. | ||
22 | Paul Gortmaker : new reset code, reset card after probe at boot. | ||
23 | Paul Gortmaker : multiple card support for module users. | ||
24 | Paul Gortmaker : Support for PCI ne2k clones, similar to lance.c | ||
25 | Paul Gortmaker : Allow users with bad cards to avoid full probe. | ||
26 | Paul Gortmaker : PCI probe changes, more PCI cards supported. | ||
27 | rjohnson@analogic.com : Changed init order so an interrupt will only | ||
28 | occur after memory is allocated for dev->priv. Deallocated memory | ||
29 | last in cleanup_modue() | ||
30 | Richard Guenther : Added support for ISAPnP cards | ||
31 | Paul Gortmaker : Discontinued PCI support - use ne2k-pci.c instead. | ||
32 | Hayato Fujiwara : Add m32r support. | ||
33 | |||
34 | */ | ||
35 | |||
36 | /* Routines for the NatSemi-based designs (NE[12]000). */ | ||
37 | |||
38 | static const char version1[] = | ||
39 | "ne.c:v1.10 9/23/94 Donald Becker (becker@scyld.com)\n"; | ||
40 | static const char version2[] = | ||
41 | "Last modified Nov 1, 2000 by Paul Gortmaker\n"; | ||
42 | |||
43 | |||
44 | #include <linux/module.h> | ||
45 | #include <linux/kernel.h> | ||
46 | #include <linux/errno.h> | ||
47 | #include <linux/isapnp.h> | ||
48 | #include <linux/init.h> | ||
49 | #include <linux/interrupt.h> | ||
50 | #include <linux/delay.h> | ||
51 | #include <linux/netdevice.h> | ||
52 | #include <linux/etherdevice.h> | ||
53 | #include <linux/jiffies.h> | ||
54 | #include <linux/platform_device.h> | ||
55 | |||
56 | #include <asm/system.h> | ||
57 | #include <asm/io.h> | ||
58 | |||
59 | #include "8390.h" | ||
60 | |||
61 | #define DRV_NAME "ne" | ||
62 | |||
63 | /* Some defines that people can play with if so inclined. */ | ||
64 | |||
65 | /* Do we support clones that don't adhere to 14,15 of the SAprom ? */ | ||
66 | #define SUPPORT_NE_BAD_CLONES | ||
67 | /* 0xbad = bad sig or no reset ack */ | ||
68 | #define BAD 0xbad | ||
69 | |||
70 | #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ | ||
71 | static struct platform_device *pdev_ne[MAX_NE_CARDS]; | ||
72 | static int io[MAX_NE_CARDS]; | ||
73 | static int irq[MAX_NE_CARDS]; | ||
74 | static int bad[MAX_NE_CARDS]; | ||
75 | |||
76 | #ifdef MODULE | ||
77 | module_param_array(io, int, NULL, 0); | ||
78 | module_param_array(irq, int, NULL, 0); | ||
79 | module_param_array(bad, int, NULL, 0); | ||
80 | MODULE_PARM_DESC(io, "I/O base address(es),required"); | ||
81 | MODULE_PARM_DESC(irq, "IRQ number(s)"); | ||
82 | MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures"); | ||
83 | MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver"); | ||
84 | MODULE_LICENSE("GPL"); | ||
85 | #endif /* MODULE */ | ||
86 | |||
87 | /* Do we perform extra sanity checks on stuff ? */ | ||
88 | /* #define NE_SANITY_CHECK */ | ||
89 | |||
90 | /* Do we implement the read before write bugfix ? */ | ||
91 | /* #define NE_RW_BUGFIX */ | ||
92 | |||
93 | /* Do we have a non std. amount of memory? (in units of 256 byte pages) */ | ||
94 | /* #define PACKETBUF_MEMSIZE 0x40 */ | ||
95 | |||
96 | /* This is set up so that no ISA autoprobe takes place. We can't guarantee | ||
97 | that the ne2k probe is the last 8390 based probe to take place (as it | ||
98 | is at boot) and so the probe will get confused by any other 8390 cards. | ||
99 | ISA device autoprobes on a running machine are not recommended anyway. */ | ||
100 | #if !defined(MODULE) && (defined(CONFIG_ISA) || defined(CONFIG_M32R)) | ||
101 | /* Do we need a portlist for the ISA auto-probe ? */ | ||
102 | #define NEEDS_PORTLIST | ||
103 | #endif | ||
104 | |||
105 | /* A zero-terminated list of I/O addresses to be probed at boot. */ | ||
106 | #ifdef NEEDS_PORTLIST | ||
107 | static unsigned int netcard_portlist[] __initdata = { | ||
108 | 0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0 | ||
109 | }; | ||
110 | #endif | ||
111 | |||
112 | static struct isapnp_device_id isapnp_clone_list[] __initdata = { | ||
113 | { ISAPNP_CARD_ID('A','X','E',0x2011), | ||
114 | ISAPNP_VENDOR('A','X','E'), ISAPNP_FUNCTION(0x2011), | ||
115 | (long) "NetGear EA201" }, | ||
116 | { ISAPNP_ANY_ID, ISAPNP_ANY_ID, | ||
117 | ISAPNP_VENDOR('E','D','I'), ISAPNP_FUNCTION(0x0216), | ||
118 | (long) "NN NE2000" }, | ||
119 | { ISAPNP_ANY_ID, ISAPNP_ANY_ID, | ||
120 | ISAPNP_VENDOR('P','N','P'), ISAPNP_FUNCTION(0x80d6), | ||
121 | (long) "Generic PNP" }, | ||
122 | { } /* terminate list */ | ||
123 | }; | ||
124 | |||
125 | MODULE_DEVICE_TABLE(isapnp, isapnp_clone_list); | ||
126 | |||
127 | #ifdef SUPPORT_NE_BAD_CLONES | ||
128 | /* A list of bad clones that we none-the-less recognize. */ | ||
129 | static struct { const char *name8, *name16; unsigned char SAprefix[4];} | ||
130 | bad_clone_list[] __initdata = { | ||
131 | {"DE100", "DE200", {0x00, 0xDE, 0x01,}}, | ||
132 | {"DE120", "DE220", {0x00, 0x80, 0xc8,}}, | ||
133 | {"DFI1000", "DFI2000", {'D', 'F', 'I',}}, /* Original, eh? */ | ||
134 | {"EtherNext UTP8", "EtherNext UTP16", {0x00, 0x00, 0x79}}, | ||
135 | {"NE1000","NE2000-invalid", {0x00, 0x00, 0xd8}}, /* Ancient real NE1000. */ | ||
136 | {"NN1000", "NN2000", {0x08, 0x03, 0x08}}, /* Outlaw no-name clone. */ | ||
137 | {"4-DIM8","4-DIM16", {0x00,0x00,0x4d,}}, /* Outlaw 4-Dimension cards. */ | ||
138 | {"Con-Intl_8", "Con-Intl_16", {0x00, 0x00, 0x24}}, /* Connect Int'nl */ | ||
139 | {"ET-100","ET-200", {0x00, 0x45, 0x54}}, /* YANG and YA clone */ | ||
140 | {"COMPEX","COMPEX16",{0x00,0x80,0x48}}, /* Broken ISA Compex cards */ | ||
141 | {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */ | ||
142 | {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */ | ||
143 | {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */ | ||
144 | #ifdef CONFIG_MACH_TX49XX | ||
145 | {"RBHMA4X00-RTL8019", "RBHMA4X00-RTL8019", {0x00, 0x60, 0x0a}}, /* Toshiba built-in */ | ||
146 | #endif | ||
147 | {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */ | ||
148 | {NULL,} | ||
149 | }; | ||
150 | #endif | ||
151 | |||
152 | /* ---- No user-serviceable parts below ---- */ | ||
153 | |||
154 | #define NE_BASE (dev->base_addr) | ||
155 | #define NE_CMD 0x00 | ||
156 | #define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ | ||
157 | #define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */ | ||
158 | #define NE_IO_EXTENT 0x20 | ||
159 | |||
160 | #define NE1SM_START_PG 0x20 /* First page of TX buffer */ | ||
161 | #define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ | ||
162 | #define NESM_START_PG 0x40 /* First page of TX buffer */ | ||
163 | #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
164 | |||
165 | #if defined(CONFIG_PLAT_MAPPI) | ||
166 | # define DCR_VAL 0x4b | ||
167 | #elif defined(CONFIG_PLAT_OAKS32R) || \ | ||
168 | defined(CONFIG_MACH_TX49XX) | ||
169 | # define DCR_VAL 0x48 /* 8-bit mode */ | ||
170 | #else | ||
171 | # define DCR_VAL 0x49 | ||
172 | #endif | ||
173 | |||
174 | static int ne_probe1(struct net_device *dev, unsigned long ioaddr); | ||
175 | static int ne_probe_isapnp(struct net_device *dev); | ||
176 | |||
177 | static void ne_reset_8390(struct net_device *dev); | ||
178 | static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
179 | int ring_page); | ||
180 | static void ne_block_input(struct net_device *dev, int count, | ||
181 | struct sk_buff *skb, int ring_offset); | ||
182 | static void ne_block_output(struct net_device *dev, const int count, | ||
183 | const unsigned char *buf, const int start_page); | ||
184 | |||
185 | |||
186 | /* Probe for various non-shared-memory ethercards. | ||
187 | |||
188 | NEx000-clone boards have a Station Address PROM (SAPROM) in the packet | ||
189 | buffer memory space. NE2000 clones have 0x57,0x57 in bytes 0x0e,0x0f of | ||
190 | the SAPROM, while other supposed NE2000 clones must be detected by their | ||
191 | SA prefix. | ||
192 | |||
193 | Reading the SAPROM from a word-wide card with the 8390 set in byte-wide | ||
194 | mode results in doubled values, which can be detected and compensated for. | ||
195 | |||
196 | The probe is also responsible for initializing the card and filling | ||
197 | in the 'dev' and 'ei_status' structures. | ||
198 | |||
199 | We use the minimum memory size for some ethercard product lines, iff we can't | ||
200 | distinguish models. You can increase the packet buffer size by setting | ||
201 | PACKETBUF_MEMSIZE. Reported Cabletron packet buffer locations are: | ||
202 | E1010 starts at 0x100 and ends at 0x2000. | ||
203 | E1010-x starts at 0x100 and ends at 0x8000. ("-x" means "more memory") | ||
204 | E2010 starts at 0x100 and ends at 0x4000. | ||
205 | E2010-x starts at 0x100 and ends at 0xffff. */ | ||
206 | |||
207 | static int __init do_ne_probe(struct net_device *dev) | ||
208 | { | ||
209 | unsigned long base_addr = dev->base_addr; | ||
210 | #ifdef NEEDS_PORTLIST | ||
211 | int orig_irq = dev->irq; | ||
212 | #endif | ||
213 | |||
214 | /* First check any supplied i/o locations. User knows best. <cough> */ | ||
215 | if (base_addr > 0x1ff) { /* Check a single specified location. */ | ||
216 | int ret = ne_probe1(dev, base_addr); | ||
217 | if (ret) | ||
218 | printk(KERN_WARNING "ne.c: No NE*000 card found at " | ||
219 | "i/o = %#lx\n", base_addr); | ||
220 | return ret; | ||
221 | } | ||
222 | else if (base_addr != 0) /* Don't probe at all. */ | ||
223 | return -ENXIO; | ||
224 | |||
225 | /* Then look for any installed ISAPnP clones */ | ||
226 | if (isapnp_present() && (ne_probe_isapnp(dev) == 0)) | ||
227 | return 0; | ||
228 | |||
229 | #ifdef NEEDS_PORTLIST | ||
230 | /* Last resort. The semi-risky ISA auto-probe. */ | ||
231 | for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) { | ||
232 | int ioaddr = netcard_portlist[base_addr]; | ||
233 | dev->irq = orig_irq; | ||
234 | if (ne_probe1(dev, ioaddr) == 0) | ||
235 | return 0; | ||
236 | } | ||
237 | #endif | ||
238 | |||
239 | return -ENODEV; | ||
240 | } | ||
241 | |||
242 | static int __init ne_probe_isapnp(struct net_device *dev) | ||
243 | { | ||
244 | int i; | ||
245 | |||
246 | for (i = 0; isapnp_clone_list[i].vendor != 0; i++) { | ||
247 | struct pnp_dev *idev = NULL; | ||
248 | |||
249 | while ((idev = pnp_find_dev(NULL, | ||
250 | isapnp_clone_list[i].vendor, | ||
251 | isapnp_clone_list[i].function, | ||
252 | idev))) { | ||
253 | /* Avoid already found cards from previous calls */ | ||
254 | if (pnp_device_attach(idev) < 0) | ||
255 | continue; | ||
256 | if (pnp_activate_dev(idev) < 0) { | ||
257 | pnp_device_detach(idev); | ||
258 | continue; | ||
259 | } | ||
260 | /* if no io and irq, search for next */ | ||
261 | if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) { | ||
262 | pnp_device_detach(idev); | ||
263 | continue; | ||
264 | } | ||
265 | /* found it */ | ||
266 | dev->base_addr = pnp_port_start(idev, 0); | ||
267 | dev->irq = pnp_irq(idev, 0); | ||
268 | printk(KERN_INFO "ne.c: ISAPnP reports %s at i/o %#lx, irq %d.\n", | ||
269 | (char *) isapnp_clone_list[i].driver_data, | ||
270 | dev->base_addr, dev->irq); | ||
271 | if (ne_probe1(dev, dev->base_addr) != 0) { /* Shouldn't happen. */ | ||
272 | printk(KERN_ERR "ne.c: Probe of ISAPnP card at %#lx failed.\n", dev->base_addr); | ||
273 | pnp_device_detach(idev); | ||
274 | return -ENXIO; | ||
275 | } | ||
276 | ei_status.priv = (unsigned long)idev; | ||
277 | break; | ||
278 | } | ||
279 | if (!idev) | ||
280 | continue; | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | return -ENODEV; | ||
285 | } | ||
286 | |||
287 | static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) | ||
288 | { | ||
289 | int i; | ||
290 | unsigned char SA_prom[32]; | ||
291 | int wordlength = 2; | ||
292 | const char *name = NULL; | ||
293 | int start_page, stop_page; | ||
294 | int neX000, ctron, copam, bad_card; | ||
295 | int reg0, ret; | ||
296 | static unsigned version_printed; | ||
297 | |||
298 | if (!request_region(ioaddr, NE_IO_EXTENT, DRV_NAME)) | ||
299 | return -EBUSY; | ||
300 | |||
301 | reg0 = inb_p(ioaddr); | ||
302 | if (reg0 == 0xFF) { | ||
303 | ret = -ENODEV; | ||
304 | goto err_out; | ||
305 | } | ||
306 | |||
307 | /* Do a preliminary verification that we have a 8390. */ | ||
308 | { | ||
309 | int regd; | ||
310 | outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); | ||
311 | regd = inb_p(ioaddr + 0x0d); | ||
312 | outb_p(0xff, ioaddr + 0x0d); | ||
313 | outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD); | ||
314 | inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ | ||
315 | if (inb_p(ioaddr + EN0_COUNTER0) != 0) { | ||
316 | outb_p(reg0, ioaddr); | ||
317 | outb_p(regd, ioaddr + 0x0d); /* Restore the old values. */ | ||
318 | ret = -ENODEV; | ||
319 | goto err_out; | ||
320 | } | ||
321 | } | ||
322 | |||
323 | if (ei_debug && version_printed++ == 0) | ||
324 | printk(KERN_INFO "%s%s", version1, version2); | ||
325 | |||
326 | printk(KERN_INFO "NE*000 ethercard probe at %#3lx:", ioaddr); | ||
327 | |||
328 | /* A user with a poor card that fails to ack the reset, or that | ||
329 | does not have a valid 0x57,0x57 signature can still use this | ||
330 | without having to recompile. Specifying an i/o address along | ||
331 | with an otherwise unused dev->mem_end value of "0xBAD" will | ||
332 | cause the driver to skip these parts of the probe. */ | ||
333 | |||
334 | bad_card = ((dev->base_addr != 0) && (dev->mem_end == BAD)); | ||
335 | |||
336 | /* Reset card. Who knows what dain-bramaged state it was left in. */ | ||
337 | |||
338 | { | ||
339 | unsigned long reset_start_time = jiffies; | ||
340 | |||
341 | /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ | ||
342 | outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); | ||
343 | |||
344 | while ((inb_p(ioaddr + EN0_ISR) & ENISR_RESET) == 0) | ||
345 | if (time_after(jiffies, reset_start_time + 2*HZ/100)) { | ||
346 | if (bad_card) { | ||
347 | printk(" (warning: no reset ack)"); | ||
348 | break; | ||
349 | } else { | ||
350 | printk(" not found (no reset ack).\n"); | ||
351 | ret = -ENODEV; | ||
352 | goto err_out; | ||
353 | } | ||
354 | } | ||
355 | |||
356 | outb_p(0xff, ioaddr + EN0_ISR); /* Ack all intr. */ | ||
357 | } | ||
358 | |||
359 | /* Read the 16 bytes of station address PROM. | ||
360 | We must first initialize registers, similar to NS8390p_init(eifdev, 0). | ||
361 | We can't reliably read the SAPROM address without this. | ||
362 | (I learned the hard way!). */ | ||
363 | { | ||
364 | struct {unsigned char value, offset; } program_seq[] = | ||
365 | { | ||
366 | {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ | ||
367 | {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ | ||
368 | {0x00, EN0_RCNTLO}, /* Clear the count regs. */ | ||
369 | {0x00, EN0_RCNTHI}, | ||
370 | {0x00, EN0_IMR}, /* Mask completion irq. */ | ||
371 | {0xFF, EN0_ISR}, | ||
372 | {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ | ||
373 | {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ | ||
374 | {32, EN0_RCNTLO}, | ||
375 | {0x00, EN0_RCNTHI}, | ||
376 | {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ | ||
377 | {0x00, EN0_RSARHI}, | ||
378 | {E8390_RREAD+E8390_START, E8390_CMD}, | ||
379 | }; | ||
380 | |||
381 | for (i = 0; i < ARRAY_SIZE(program_seq); i++) | ||
382 | outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); | ||
383 | |||
384 | } | ||
385 | for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) { | ||
386 | SA_prom[i] = inb(ioaddr + NE_DATAPORT); | ||
387 | SA_prom[i+1] = inb(ioaddr + NE_DATAPORT); | ||
388 | if (SA_prom[i] != SA_prom[i+1]) | ||
389 | wordlength = 1; | ||
390 | } | ||
391 | |||
392 | if (wordlength == 2) | ||
393 | { | ||
394 | for (i = 0; i < 16; i++) | ||
395 | SA_prom[i] = SA_prom[i+i]; | ||
396 | /* We must set the 8390 for word mode. */ | ||
397 | outb_p(DCR_VAL, ioaddr + EN0_DCFG); | ||
398 | start_page = NESM_START_PG; | ||
399 | |||
400 | /* | ||
401 | * Realtek RTL8019AS datasheet says that the PSTOP register | ||
402 | * shouldn't exceed 0x60 in 8-bit mode. | ||
403 | * This chip can be identified by reading the signature from | ||
404 | * the remote byte count registers (otherwise write-only)... | ||
405 | */ | ||
406 | if ((DCR_VAL & 0x01) == 0 && /* 8-bit mode */ | ||
407 | inb(ioaddr + EN0_RCNTLO) == 0x50 && | ||
408 | inb(ioaddr + EN0_RCNTHI) == 0x70) | ||
409 | stop_page = 0x60; | ||
410 | else | ||
411 | stop_page = NESM_STOP_PG; | ||
412 | } else { | ||
413 | start_page = NE1SM_START_PG; | ||
414 | stop_page = NE1SM_STOP_PG; | ||
415 | } | ||
416 | |||
417 | #if defined(CONFIG_PLAT_MAPPI) || defined(CONFIG_PLAT_OAKS32R) | ||
418 | neX000 = ((SA_prom[14] == 0x57 && SA_prom[15] == 0x57) | ||
419 | || (SA_prom[14] == 0x42 && SA_prom[15] == 0x42)); | ||
420 | #else | ||
421 | neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57); | ||
422 | #endif | ||
423 | ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d); | ||
424 | copam = (SA_prom[14] == 0x49 && SA_prom[15] == 0x00); | ||
425 | |||
426 | /* Set up the rest of the parameters. */ | ||
427 | if (neX000 || bad_card || copam) { | ||
428 | name = (wordlength == 2) ? "NE2000" : "NE1000"; | ||
429 | } | ||
430 | else if (ctron) | ||
431 | { | ||
432 | name = (wordlength == 2) ? "Ctron-8" : "Ctron-16"; | ||
433 | start_page = 0x01; | ||
434 | stop_page = (wordlength == 2) ? 0x40 : 0x20; | ||
435 | } | ||
436 | else | ||
437 | { | ||
438 | #ifdef SUPPORT_NE_BAD_CLONES | ||
439 | /* Ack! Well, there might be a *bad* NE*000 clone there. | ||
440 | Check for total bogus addresses. */ | ||
441 | for (i = 0; bad_clone_list[i].name8; i++) | ||
442 | { | ||
443 | if (SA_prom[0] == bad_clone_list[i].SAprefix[0] && | ||
444 | SA_prom[1] == bad_clone_list[i].SAprefix[1] && | ||
445 | SA_prom[2] == bad_clone_list[i].SAprefix[2]) | ||
446 | { | ||
447 | if (wordlength == 2) | ||
448 | { | ||
449 | name = bad_clone_list[i].name16; | ||
450 | } else { | ||
451 | name = bad_clone_list[i].name8; | ||
452 | } | ||
453 | break; | ||
454 | } | ||
455 | } | ||
456 | if (bad_clone_list[i].name8 == NULL) | ||
457 | { | ||
458 | printk(" not found (invalid signature %2.2x %2.2x).\n", | ||
459 | SA_prom[14], SA_prom[15]); | ||
460 | ret = -ENXIO; | ||
461 | goto err_out; | ||
462 | } | ||
463 | #else | ||
464 | printk(" not found.\n"); | ||
465 | ret = -ENXIO; | ||
466 | goto err_out; | ||
467 | #endif | ||
468 | } | ||
469 | |||
470 | if (dev->irq < 2) | ||
471 | { | ||
472 | unsigned long cookie = probe_irq_on(); | ||
473 | outb_p(0x50, ioaddr + EN0_IMR); /* Enable one interrupt. */ | ||
474 | outb_p(0x00, ioaddr + EN0_RCNTLO); | ||
475 | outb_p(0x00, ioaddr + EN0_RCNTHI); | ||
476 | outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */ | ||
477 | mdelay(10); /* wait 10ms for interrupt to propagate */ | ||
478 | outb_p(0x00, ioaddr + EN0_IMR); /* Mask it again. */ | ||
479 | dev->irq = probe_irq_off(cookie); | ||
480 | if (ei_debug > 2) | ||
481 | printk(" autoirq is %d\n", dev->irq); | ||
482 | } else if (dev->irq == 2) | ||
483 | /* Fixup for users that don't know that IRQ 2 is really IRQ 9, | ||
484 | or don't know which one to set. */ | ||
485 | dev->irq = 9; | ||
486 | |||
487 | if (! dev->irq) { | ||
488 | printk(" failed to detect IRQ line.\n"); | ||
489 | ret = -EAGAIN; | ||
490 | goto err_out; | ||
491 | } | ||
492 | |||
493 | /* Snarf the interrupt now. There's no point in waiting since we cannot | ||
494 | share and the board will usually be enabled. */ | ||
495 | ret = request_irq(dev->irq, eip_interrupt, 0, name, dev); | ||
496 | if (ret) { | ||
497 | printk (" unable to get IRQ %d (errno=%d).\n", dev->irq, ret); | ||
498 | goto err_out; | ||
499 | } | ||
500 | |||
501 | dev->base_addr = ioaddr; | ||
502 | |||
503 | #ifdef CONFIG_PLAT_MAPPI | ||
504 | outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, | ||
505 | ioaddr + E8390_CMD); /* 0x61 */ | ||
506 | for (i = 0 ; i < ETHER_ADDR_LEN ; i++) { | ||
507 | dev->dev_addr[i] = SA_prom[i] | ||
508 | = inb_p(ioaddr + EN1_PHYS_SHIFT(i)); | ||
509 | } | ||
510 | #else | ||
511 | for(i = 0; i < ETHER_ADDR_LEN; i++) { | ||
512 | dev->dev_addr[i] = SA_prom[i]; | ||
513 | } | ||
514 | #endif | ||
515 | |||
516 | printk("%pM\n", dev->dev_addr); | ||
517 | |||
518 | ei_status.name = name; | ||
519 | ei_status.tx_start_page = start_page; | ||
520 | ei_status.stop_page = stop_page; | ||
521 | |||
522 | /* Use 16-bit mode only if this wasn't overridden by DCR_VAL */ | ||
523 | ei_status.word16 = (wordlength == 2 && (DCR_VAL & 0x01)); | ||
524 | |||
525 | ei_status.rx_start_page = start_page + TX_PAGES; | ||
526 | #ifdef PACKETBUF_MEMSIZE | ||
527 | /* Allow the packet buffer size to be overridden by know-it-alls. */ | ||
528 | ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; | ||
529 | #endif | ||
530 | |||
531 | ei_status.reset_8390 = &ne_reset_8390; | ||
532 | ei_status.block_input = &ne_block_input; | ||
533 | ei_status.block_output = &ne_block_output; | ||
534 | ei_status.get_8390_hdr = &ne_get_8390_hdr; | ||
535 | ei_status.priv = 0; | ||
536 | |||
537 | dev->netdev_ops = &eip_netdev_ops; | ||
538 | NS8390p_init(dev, 0); | ||
539 | |||
540 | ret = register_netdev(dev); | ||
541 | if (ret) | ||
542 | goto out_irq; | ||
543 | printk(KERN_INFO "%s: %s found at %#lx, using IRQ %d.\n", | ||
544 | dev->name, name, ioaddr, dev->irq); | ||
545 | return 0; | ||
546 | |||
547 | out_irq: | ||
548 | free_irq(dev->irq, dev); | ||
549 | err_out: | ||
550 | release_region(ioaddr, NE_IO_EXTENT); | ||
551 | return ret; | ||
552 | } | ||
553 | |||
554 | /* Hard reset the card. This used to pause for the same period that a | ||
555 | 8390 reset command required, but that shouldn't be necessary. */ | ||
556 | |||
557 | static void ne_reset_8390(struct net_device *dev) | ||
558 | { | ||
559 | unsigned long reset_start_time = jiffies; | ||
560 | |||
561 | if (ei_debug > 1) | ||
562 | printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies); | ||
563 | |||
564 | /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ | ||
565 | outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); | ||
566 | |||
567 | ei_status.txing = 0; | ||
568 | ei_status.dmaing = 0; | ||
569 | |||
570 | /* This check _should_not_ be necessary, omit eventually. */ | ||
571 | while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) | ||
572 | if (time_after(jiffies, reset_start_time + 2*HZ/100)) { | ||
573 | printk(KERN_WARNING "%s: ne_reset_8390() did not complete.\n", dev->name); | ||
574 | break; | ||
575 | } | ||
576 | outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ | ||
577 | } | ||
578 | |||
579 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
580 | we don't need to be concerned with ring wrap as the header will be at | ||
581 | the start of a page, so we optimize accordingly. */ | ||
582 | |||
583 | static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
584 | { | ||
585 | int nic_base = dev->base_addr; | ||
586 | |||
587 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
588 | |||
589 | if (ei_status.dmaing) | ||
590 | { | ||
591 | printk(KERN_EMERG "%s: DMAing conflict in ne_get_8390_hdr " | ||
592 | "[DMAstat:%d][irqlock:%d].\n", | ||
593 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
594 | return; | ||
595 | } | ||
596 | |||
597 | ei_status.dmaing |= 0x01; | ||
598 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); | ||
599 | outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); | ||
600 | outb_p(0, nic_base + EN0_RCNTHI); | ||
601 | outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ | ||
602 | outb_p(ring_page, nic_base + EN0_RSARHI); | ||
603 | outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
604 | |||
605 | if (ei_status.word16) | ||
606 | insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1); | ||
607 | else | ||
608 | insb(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)); | ||
609 | |||
610 | outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
611 | ei_status.dmaing &= ~0x01; | ||
612 | |||
613 | le16_to_cpus(&hdr->count); | ||
614 | } | ||
615 | |||
616 | /* Block input and output, similar to the Crynwr packet driver. If you | ||
617 | are porting to a new ethercard, look at the packet driver source for hints. | ||
618 | The NEx000 doesn't share the on-board packet memory -- you have to put | ||
619 | the packet out through the "remote DMA" dataport using outb. */ | ||
620 | |||
621 | static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
622 | { | ||
623 | #ifdef NE_SANITY_CHECK | ||
624 | int xfer_count = count; | ||
625 | #endif | ||
626 | int nic_base = dev->base_addr; | ||
627 | char *buf = skb->data; | ||
628 | |||
629 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
630 | if (ei_status.dmaing) | ||
631 | { | ||
632 | printk(KERN_EMERG "%s: DMAing conflict in ne_block_input " | ||
633 | "[DMAstat:%d][irqlock:%d].\n", | ||
634 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
635 | return; | ||
636 | } | ||
637 | ei_status.dmaing |= 0x01; | ||
638 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); | ||
639 | outb_p(count & 0xff, nic_base + EN0_RCNTLO); | ||
640 | outb_p(count >> 8, nic_base + EN0_RCNTHI); | ||
641 | outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); | ||
642 | outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); | ||
643 | outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
644 | if (ei_status.word16) | ||
645 | { | ||
646 | insw(NE_BASE + NE_DATAPORT,buf,count>>1); | ||
647 | if (count & 0x01) | ||
648 | { | ||
649 | buf[count-1] = inb(NE_BASE + NE_DATAPORT); | ||
650 | #ifdef NE_SANITY_CHECK | ||
651 | xfer_count++; | ||
652 | #endif | ||
653 | } | ||
654 | } else { | ||
655 | insb(NE_BASE + NE_DATAPORT, buf, count); | ||
656 | } | ||
657 | |||
658 | #ifdef NE_SANITY_CHECK | ||
659 | /* This was for the ALPHA version only, but enough people have | ||
660 | been encountering problems so it is still here. If you see | ||
661 | this message you either 1) have a slightly incompatible clone | ||
662 | or 2) have noise/speed problems with your bus. */ | ||
663 | |||
664 | if (ei_debug > 1) | ||
665 | { | ||
666 | /* DMA termination address check... */ | ||
667 | int addr, tries = 20; | ||
668 | do { | ||
669 | /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here | ||
670 | -- it's broken for Rx on some cards! */ | ||
671 | int high = inb_p(nic_base + EN0_RSARHI); | ||
672 | int low = inb_p(nic_base + EN0_RSARLO); | ||
673 | addr = (high << 8) + low; | ||
674 | if (((ring_offset + xfer_count) & 0xff) == low) | ||
675 | break; | ||
676 | } while (--tries > 0); | ||
677 | if (tries <= 0) | ||
678 | printk(KERN_WARNING "%s: RX transfer address mismatch," | ||
679 | "%#4.4x (expected) vs. %#4.4x (actual).\n", | ||
680 | dev->name, ring_offset + xfer_count, addr); | ||
681 | } | ||
682 | #endif | ||
683 | outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
684 | ei_status.dmaing &= ~0x01; | ||
685 | } | ||
686 | |||
687 | static void ne_block_output(struct net_device *dev, int count, | ||
688 | const unsigned char *buf, const int start_page) | ||
689 | { | ||
690 | int nic_base = NE_BASE; | ||
691 | unsigned long dma_start; | ||
692 | #ifdef NE_SANITY_CHECK | ||
693 | int retries = 0; | ||
694 | #endif | ||
695 | |||
696 | /* Round the count up for word writes. Do we need to do this? | ||
697 | What effect will an odd byte count have on the 8390? | ||
698 | I should check someday. */ | ||
699 | |||
700 | if (ei_status.word16 && (count & 0x01)) | ||
701 | count++; | ||
702 | |||
703 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
704 | if (ei_status.dmaing) | ||
705 | { | ||
706 | printk(KERN_EMERG "%s: DMAing conflict in ne_block_output." | ||
707 | "[DMAstat:%d][irqlock:%d]\n", | ||
708 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
709 | return; | ||
710 | } | ||
711 | ei_status.dmaing |= 0x01; | ||
712 | /* We should already be in page 0, but to be safe... */ | ||
713 | outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); | ||
714 | |||
715 | #ifdef NE_SANITY_CHECK | ||
716 | retry: | ||
717 | #endif | ||
718 | |||
719 | #ifdef NE8390_RW_BUGFIX | ||
720 | /* Handle the read-before-write bug the same way as the | ||
721 | Crynwr packet driver -- the NatSemi method doesn't work. | ||
722 | Actually this doesn't always work either, but if you have | ||
723 | problems with your NEx000 this is better than nothing! */ | ||
724 | |||
725 | outb_p(0x42, nic_base + EN0_RCNTLO); | ||
726 | outb_p(0x00, nic_base + EN0_RCNTHI); | ||
727 | outb_p(0x42, nic_base + EN0_RSARLO); | ||
728 | outb_p(0x00, nic_base + EN0_RSARHI); | ||
729 | outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
730 | /* Make certain that the dummy read has occurred. */ | ||
731 | udelay(6); | ||
732 | #endif | ||
733 | |||
734 | outb_p(ENISR_RDC, nic_base + EN0_ISR); | ||
735 | |||
736 | /* Now the normal output. */ | ||
737 | outb_p(count & 0xff, nic_base + EN0_RCNTLO); | ||
738 | outb_p(count >> 8, nic_base + EN0_RCNTHI); | ||
739 | outb_p(0x00, nic_base + EN0_RSARLO); | ||
740 | outb_p(start_page, nic_base + EN0_RSARHI); | ||
741 | |||
742 | outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD); | ||
743 | if (ei_status.word16) { | ||
744 | outsw(NE_BASE + NE_DATAPORT, buf, count>>1); | ||
745 | } else { | ||
746 | outsb(NE_BASE + NE_DATAPORT, buf, count); | ||
747 | } | ||
748 | |||
749 | dma_start = jiffies; | ||
750 | |||
751 | #ifdef NE_SANITY_CHECK | ||
752 | /* This was for the ALPHA version only, but enough people have | ||
753 | been encountering problems so it is still here. */ | ||
754 | |||
755 | if (ei_debug > 1) | ||
756 | { | ||
757 | /* DMA termination address check... */ | ||
758 | int addr, tries = 20; | ||
759 | do { | ||
760 | int high = inb_p(nic_base + EN0_RSARHI); | ||
761 | int low = inb_p(nic_base + EN0_RSARLO); | ||
762 | addr = (high << 8) + low; | ||
763 | if ((start_page << 8) + count == addr) | ||
764 | break; | ||
765 | } while (--tries > 0); | ||
766 | |||
767 | if (tries <= 0) | ||
768 | { | ||
769 | printk(KERN_WARNING "%s: Tx packet transfer address mismatch," | ||
770 | "%#4.4x (expected) vs. %#4.4x (actual).\n", | ||
771 | dev->name, (start_page << 8) + count, addr); | ||
772 | if (retries++ == 0) | ||
773 | goto retry; | ||
774 | } | ||
775 | } | ||
776 | #endif | ||
777 | |||
778 | while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) | ||
779 | if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ | ||
780 | printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); | ||
781 | ne_reset_8390(dev); | ||
782 | NS8390p_init(dev, 1); | ||
783 | break; | ||
784 | } | ||
785 | |||
786 | outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
787 | ei_status.dmaing &= ~0x01; | ||
788 | } | ||
789 | |||
790 | static int __init ne_drv_probe(struct platform_device *pdev) | ||
791 | { | ||
792 | struct net_device *dev; | ||
793 | int err, this_dev = pdev->id; | ||
794 | struct resource *res; | ||
795 | |||
796 | dev = alloc_eip_netdev(); | ||
797 | if (!dev) | ||
798 | return -ENOMEM; | ||
799 | |||
800 | /* ne.c doesn't populate resources in platform_device, but | ||
801 | * rbtx4927_ne_init and rbtx4938_ne_init do register devices | ||
802 | * with resources. | ||
803 | */ | ||
804 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
805 | if (res) { | ||
806 | dev->base_addr = res->start; | ||
807 | dev->irq = platform_get_irq(pdev, 0); | ||
808 | } else { | ||
809 | if (this_dev < 0 || this_dev >= MAX_NE_CARDS) { | ||
810 | free_netdev(dev); | ||
811 | return -EINVAL; | ||
812 | } | ||
813 | dev->base_addr = io[this_dev]; | ||
814 | dev->irq = irq[this_dev]; | ||
815 | dev->mem_end = bad[this_dev]; | ||
816 | } | ||
817 | err = do_ne_probe(dev); | ||
818 | if (err) { | ||
819 | free_netdev(dev); | ||
820 | return err; | ||
821 | } | ||
822 | platform_set_drvdata(pdev, dev); | ||
823 | |||
824 | /* Update with any values found by probing, don't update if | ||
825 | * resources were specified. | ||
826 | */ | ||
827 | if (!res) { | ||
828 | io[this_dev] = dev->base_addr; | ||
829 | irq[this_dev] = dev->irq; | ||
830 | } | ||
831 | return 0; | ||
832 | } | ||
833 | |||
834 | static int ne_drv_remove(struct platform_device *pdev) | ||
835 | { | ||
836 | struct net_device *dev = platform_get_drvdata(pdev); | ||
837 | |||
838 | if (dev) { | ||
839 | struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; | ||
840 | netif_device_detach(dev); | ||
841 | unregister_netdev(dev); | ||
842 | if (idev) | ||
843 | pnp_device_detach(idev); | ||
844 | /* Careful ne_drv_remove can be called twice, once from | ||
845 | * the platform_driver.remove and again when the | ||
846 | * platform_device is being removed. | ||
847 | */ | ||
848 | ei_status.priv = 0; | ||
849 | free_irq(dev->irq, dev); | ||
850 | release_region(dev->base_addr, NE_IO_EXTENT); | ||
851 | free_netdev(dev); | ||
852 | platform_set_drvdata(pdev, NULL); | ||
853 | } | ||
854 | return 0; | ||
855 | } | ||
856 | |||
857 | /* Remove unused devices or all if true. */ | ||
858 | static void ne_loop_rm_unreg(int all) | ||
859 | { | ||
860 | int this_dev; | ||
861 | struct platform_device *pdev; | ||
862 | for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { | ||
863 | pdev = pdev_ne[this_dev]; | ||
864 | /* No network device == unused */ | ||
865 | if (pdev && (!platform_get_drvdata(pdev) || all)) { | ||
866 | ne_drv_remove(pdev); | ||
867 | platform_device_unregister(pdev); | ||
868 | pdev_ne[this_dev] = NULL; | ||
869 | } | ||
870 | } | ||
871 | } | ||
872 | |||
873 | #ifdef CONFIG_PM | ||
874 | static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state) | ||
875 | { | ||
876 | struct net_device *dev = platform_get_drvdata(pdev); | ||
877 | |||
878 | if (netif_running(dev)) { | ||
879 | struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; | ||
880 | netif_device_detach(dev); | ||
881 | if (idev) | ||
882 | pnp_stop_dev(idev); | ||
883 | } | ||
884 | return 0; | ||
885 | } | ||
886 | |||
887 | static int ne_drv_resume(struct platform_device *pdev) | ||
888 | { | ||
889 | struct net_device *dev = platform_get_drvdata(pdev); | ||
890 | |||
891 | if (netif_running(dev)) { | ||
892 | struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; | ||
893 | if (idev) | ||
894 | pnp_start_dev(idev); | ||
895 | ne_reset_8390(dev); | ||
896 | NS8390p_init(dev, 1); | ||
897 | netif_device_attach(dev); | ||
898 | } | ||
899 | return 0; | ||
900 | } | ||
901 | #else | ||
902 | #define ne_drv_suspend NULL | ||
903 | #define ne_drv_resume NULL | ||
904 | #endif | ||
905 | |||
906 | static struct platform_driver ne_driver = { | ||
907 | .remove = ne_drv_remove, | ||
908 | .suspend = ne_drv_suspend, | ||
909 | .resume = ne_drv_resume, | ||
910 | .driver = { | ||
911 | .name = DRV_NAME, | ||
912 | .owner = THIS_MODULE, | ||
913 | }, | ||
914 | }; | ||
915 | |||
916 | static void __init ne_add_devices(void) | ||
917 | { | ||
918 | int this_dev; | ||
919 | struct platform_device *pdev; | ||
920 | |||
921 | for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { | ||
922 | if (pdev_ne[this_dev]) | ||
923 | continue; | ||
924 | pdev = platform_device_register_simple( | ||
925 | DRV_NAME, this_dev, NULL, 0); | ||
926 | if (IS_ERR(pdev)) | ||
927 | continue; | ||
928 | pdev_ne[this_dev] = pdev; | ||
929 | } | ||
930 | } | ||
931 | |||
932 | #ifdef MODULE | ||
933 | int __init init_module(void) | ||
934 | { | ||
935 | int retval; | ||
936 | ne_add_devices(); | ||
937 | retval = platform_driver_probe(&ne_driver, ne_drv_probe); | ||
938 | if (retval) { | ||
939 | if (io[0] == 0) | ||
940 | printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\"" | ||
941 | " value(s) for ISA cards.\n"); | ||
942 | ne_loop_rm_unreg(1); | ||
943 | return retval; | ||
944 | } | ||
945 | |||
946 | /* Unregister unused platform_devices. */ | ||
947 | ne_loop_rm_unreg(0); | ||
948 | return retval; | ||
949 | } | ||
950 | #else /* MODULE */ | ||
951 | static int __init ne_init(void) | ||
952 | { | ||
953 | int retval = platform_driver_probe(&ne_driver, ne_drv_probe); | ||
954 | |||
955 | /* Unregister unused platform_devices. */ | ||
956 | ne_loop_rm_unreg(0); | ||
957 | return retval; | ||
958 | } | ||
959 | module_init(ne_init); | ||
960 | |||
961 | struct net_device * __init ne_probe(int unit) | ||
962 | { | ||
963 | int this_dev; | ||
964 | struct net_device *dev; | ||
965 | |||
966 | /* Find an empty slot, that is no net_device and zero io port. */ | ||
967 | this_dev = 0; | ||
968 | while ((pdev_ne[this_dev] && platform_get_drvdata(pdev_ne[this_dev])) || | ||
969 | io[this_dev]) { | ||
970 | if (++this_dev == MAX_NE_CARDS) | ||
971 | return ERR_PTR(-ENOMEM); | ||
972 | } | ||
973 | |||
974 | /* Get irq, io from kernel command line */ | ||
975 | dev = alloc_eip_netdev(); | ||
976 | if (!dev) | ||
977 | return ERR_PTR(-ENOMEM); | ||
978 | |||
979 | sprintf(dev->name, "eth%d", unit); | ||
980 | netdev_boot_setup_check(dev); | ||
981 | |||
982 | io[this_dev] = dev->base_addr; | ||
983 | irq[this_dev] = dev->irq; | ||
984 | bad[this_dev] = dev->mem_end; | ||
985 | |||
986 | free_netdev(dev); | ||
987 | |||
988 | ne_add_devices(); | ||
989 | |||
990 | /* return the first device found */ | ||
991 | for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { | ||
992 | if (pdev_ne[this_dev]) { | ||
993 | dev = platform_get_drvdata(pdev_ne[this_dev]); | ||
994 | if (dev) | ||
995 | return dev; | ||
996 | } | ||
997 | } | ||
998 | |||
999 | return ERR_PTR(-ENODEV); | ||
1000 | } | ||
1001 | #endif /* MODULE */ | ||
1002 | |||
1003 | static void __exit ne_exit(void) | ||
1004 | { | ||
1005 | platform_driver_unregister(&ne_driver); | ||
1006 | ne_loop_rm_unreg(1); | ||
1007 | } | ||
1008 | module_exit(ne_exit); | ||
diff --git a/drivers/net/ethernet/8390/ne2.c b/drivers/net/ethernet/8390/ne2.c new file mode 100644 index 000000000000..70cdc6996342 --- /dev/null +++ b/drivers/net/ethernet/8390/ne2.c | |||
@@ -0,0 +1,799 @@ | |||
1 | /* ne2.c: A NE/2 Ethernet Driver for Linux. */ | ||
2 | /* | ||
3 | Based on the NE2000 driver written by Donald Becker (1992-94). | ||
4 | modified by Wim Dumon (Apr 1996) | ||
5 | |||
6 | This software may be used and distributed according to the terms | ||
7 | of the GNU General Public License, incorporated herein by reference. | ||
8 | |||
9 | The author may be reached as wimpie@linux.cc.kuleuven.ac.be | ||
10 | |||
11 | Currently supported: NE/2 | ||
12 | This patch was never tested on other MCA-ethernet adapters, but it | ||
13 | might work. Just give it a try and let me know if you have problems. | ||
14 | Also mail me if it really works, please! | ||
15 | |||
16 | Changelog: | ||
17 | Mon Feb 3 16:26:02 MET 1997 | ||
18 | - adapted the driver to work with the 2.1.25 kernel | ||
19 | - multiple ne2 support (untested) | ||
20 | - module support (untested) | ||
21 | |||
22 | Fri Aug 28 00:18:36 CET 1998 (David Weinehall) | ||
23 | - fixed a few minor typos | ||
24 | - made the MODULE_PARM conditional (it only works with the v2.1.x kernels) | ||
25 | - fixed the module support (Now it's working...) | ||
26 | |||
27 | Mon Sep 7 19:01:44 CET 1998 (David Weinehall) | ||
28 | - added support for Arco Electronics AE/2-card (experimental) | ||
29 | |||
30 | Mon Sep 14 09:53:42 CET 1998 (David Weinehall) | ||
31 | - added support for Compex ENET-16MC/P (experimental) | ||
32 | |||
33 | Tue Sep 15 16:21:12 CET 1998 (David Weinehall, Magnus Jonsson, Tomas Ogren) | ||
34 | - Miscellaneous bugfixes | ||
35 | |||
36 | Tue Sep 19 16:21:12 CET 1998 (Magnus Jonsson) | ||
37 | - Cleanup | ||
38 | |||
39 | Wed Sep 23 14:33:34 CET 1998 (David Weinehall) | ||
40 | - Restructuring and rewriting for v2.1.x compliance | ||
41 | |||
42 | Wed Oct 14 17:19:21 CET 1998 (David Weinehall) | ||
43 | - Added code that unregisters irq and proc-info | ||
44 | - Version# bump | ||
45 | |||
46 | Mon Nov 16 15:28:23 CET 1998 (Wim Dumon) | ||
47 | - pass 'dev' as last parameter of request_irq in stead of 'NULL' | ||
48 | |||
49 | Wed Feb 7 21:24:00 CET 2001 (Alfred Arnold) | ||
50 | - added support for the D-Link DE-320CT | ||
51 | |||
52 | * WARNING | ||
53 | ------- | ||
54 | This is alpha-test software. It is not guaranteed to work. As a | ||
55 | matter of fact, I'm quite sure there are *LOTS* of bugs in here. I | ||
56 | would like to hear from you if you use this driver, even if it works. | ||
57 | If it doesn't work, be sure to send me a mail with the problems ! | ||
58 | */ | ||
59 | |||
60 | static const char *version = "ne2.c:v0.91 Nov 16 1998 Wim Dumon <wimpie@kotnet.org>\n"; | ||
61 | |||
62 | #include <linux/module.h> | ||
63 | #include <linux/kernel.h> | ||
64 | #include <linux/types.h> | ||
65 | #include <linux/fcntl.h> | ||
66 | #include <linux/interrupt.h> | ||
67 | #include <linux/ioport.h> | ||
68 | #include <linux/in.h> | ||
69 | #include <linux/string.h> | ||
70 | #include <linux/errno.h> | ||
71 | #include <linux/init.h> | ||
72 | #include <linux/mca-legacy.h> | ||
73 | #include <linux/netdevice.h> | ||
74 | #include <linux/etherdevice.h> | ||
75 | #include <linux/skbuff.h> | ||
76 | #include <linux/bitops.h> | ||
77 | #include <linux/jiffies.h> | ||
78 | |||
79 | #include <asm/system.h> | ||
80 | #include <asm/io.h> | ||
81 | #include <asm/dma.h> | ||
82 | |||
83 | #include "8390.h" | ||
84 | |||
85 | #define DRV_NAME "ne2" | ||
86 | |||
87 | /* Some defines that people can play with if so inclined. */ | ||
88 | |||
89 | /* Do we perform extra sanity checks on stuff ? */ | ||
90 | /* #define NE_SANITY_CHECK */ | ||
91 | |||
92 | /* Do we implement the read before write bugfix ? */ | ||
93 | /* #define NE_RW_BUGFIX */ | ||
94 | |||
95 | /* Do we have a non std. amount of memory? (in units of 256 byte pages) */ | ||
96 | /* #define PACKETBUF_MEMSIZE 0x40 */ | ||
97 | |||
98 | |||
99 | /* ---- No user-serviceable parts below ---- */ | ||
100 | |||
101 | #define NE_BASE (dev->base_addr) | ||
102 | #define NE_CMD 0x00 | ||
103 | #define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ | ||
104 | #define NE_RESET 0x20 /* Issue a read to reset, a write to clear. */ | ||
105 | #define NE_IO_EXTENT 0x30 | ||
106 | |||
107 | #define NE1SM_START_PG 0x20 /* First page of TX buffer */ | ||
108 | #define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */ | ||
109 | #define NESM_START_PG 0x40 /* First page of TX buffer */ | ||
110 | #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
111 | |||
112 | /* From the .ADF file: */ | ||
113 | static unsigned int addresses[7] __initdata = | ||
114 | {0x1000, 0x2020, 0x8020, 0xa0a0, 0xb0b0, 0xc0c0, 0xc3d0}; | ||
115 | static int irqs[4] __initdata = {3, 4, 5, 9}; | ||
116 | |||
117 | /* From the D-Link ADF file: */ | ||
118 | static unsigned int dlink_addresses[4] __initdata = | ||
119 | {0x300, 0x320, 0x340, 0x360}; | ||
120 | static int dlink_irqs[8] __initdata = {3, 4, 5, 9, 10, 11, 14, 15}; | ||
121 | |||
122 | struct ne2_adapters_t { | ||
123 | unsigned int id; | ||
124 | char *name; | ||
125 | }; | ||
126 | |||
127 | static struct ne2_adapters_t ne2_adapters[] __initdata = { | ||
128 | { 0x6354, "Arco Ethernet Adapter AE/2" }, | ||
129 | { 0x70DE, "Compex ENET-16 MC/P" }, | ||
130 | { 0x7154, "Novell Ethernet Adapter NE/2" }, | ||
131 | { 0x56ea, "D-Link DE-320CT" }, | ||
132 | { 0x0000, NULL } | ||
133 | }; | ||
134 | |||
135 | extern int netcard_probe(struct net_device *dev); | ||
136 | |||
137 | static int ne2_probe1(struct net_device *dev, int slot); | ||
138 | |||
139 | static void ne_reset_8390(struct net_device *dev); | ||
140 | static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
141 | int ring_page); | ||
142 | static void ne_block_input(struct net_device *dev, int count, | ||
143 | struct sk_buff *skb, int ring_offset); | ||
144 | static void ne_block_output(struct net_device *dev, const int count, | ||
145 | const unsigned char *buf, const int start_page); | ||
146 | |||
147 | |||
148 | /* | ||
149 | * special code to read the DE-320's MAC address EEPROM. In contrast to a | ||
150 | * standard NE design, this is a serial EEPROM (93C46) that has to be read | ||
151 | * bit by bit. The EEPROM cotrol port at base + 0x1e has the following | ||
152 | * layout: | ||
153 | * | ||
154 | * Bit 0 = Data out (read from EEPROM) | ||
155 | * Bit 1 = Data in (write to EEPROM) | ||
156 | * Bit 2 = Clock | ||
157 | * Bit 3 = Chip Select | ||
158 | * Bit 7 = ~50 kHz clock for defined delays | ||
159 | * | ||
160 | */ | ||
161 | |||
162 | static void __init dlink_put_eeprom(unsigned char value, unsigned int addr) | ||
163 | { | ||
164 | int z; | ||
165 | unsigned char v1, v2; | ||
166 | |||
167 | /* write the value to the NIC EEPROM register */ | ||
168 | |||
169 | outb(value, addr + 0x1e); | ||
170 | |||
171 | /* now wait the clock line to toggle twice. Effectively, we are | ||
172 | waiting (at least) for one clock cycle */ | ||
173 | |||
174 | for (z = 0; z < 2; z++) { | ||
175 | do { | ||
176 | v1 = inb(addr + 0x1e); | ||
177 | v2 = inb(addr + 0x1e); | ||
178 | } | ||
179 | while (!((v1 ^ v2) & 0x80)); | ||
180 | } | ||
181 | } | ||
182 | |||
183 | static void __init dlink_send_eeprom_bit(unsigned int bit, unsigned int addr) | ||
184 | { | ||
185 | /* shift data bit into correct position */ | ||
186 | |||
187 | bit = bit << 1; | ||
188 | |||
189 | /* write value, keep clock line high for two cycles */ | ||
190 | |||
191 | dlink_put_eeprom(0x09 | bit, addr); | ||
192 | dlink_put_eeprom(0x0d | bit, addr); | ||
193 | dlink_put_eeprom(0x0d | bit, addr); | ||
194 | dlink_put_eeprom(0x09 | bit, addr); | ||
195 | } | ||
196 | |||
197 | static void __init dlink_send_eeprom_word(unsigned int value, unsigned int len, unsigned int addr) | ||
198 | { | ||
199 | int z; | ||
200 | |||
201 | /* adjust bits so that they are left-aligned in a 16-bit-word */ | ||
202 | |||
203 | value = value << (16 - len); | ||
204 | |||
205 | /* shift bits out to the EEPROM */ | ||
206 | |||
207 | for (z = 0; z < len; z++) { | ||
208 | dlink_send_eeprom_bit((value & 0x8000) >> 15, addr); | ||
209 | value = value << 1; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | static unsigned int __init dlink_get_eeprom(unsigned int eeaddr, unsigned int addr) | ||
214 | { | ||
215 | int z; | ||
216 | unsigned int value = 0; | ||
217 | |||
218 | /* pull the CS line low for a moment. This resets the EEPROM- | ||
219 | internal logic, and makes it ready for a new command. */ | ||
220 | |||
221 | dlink_put_eeprom(0x01, addr); | ||
222 | dlink_put_eeprom(0x09, addr); | ||
223 | |||
224 | /* send one start bit, read command (1 - 0), plus the address to | ||
225 | the EEPROM */ | ||
226 | |||
227 | dlink_send_eeprom_word(0x0180 | (eeaddr & 0x3f), 9, addr); | ||
228 | |||
229 | /* get the data word. We clock by sending 0s to the EEPROM, which | ||
230 | get ignored during the read process */ | ||
231 | |||
232 | for (z = 0; z < 16; z++) { | ||
233 | dlink_send_eeprom_bit(0, addr); | ||
234 | value = (value << 1) | (inb(addr + 0x1e) & 0x01); | ||
235 | } | ||
236 | |||
237 | return value; | ||
238 | } | ||
239 | |||
240 | /* | ||
241 | * Note that at boot, this probe only picks up one card at a time. | ||
242 | */ | ||
243 | |||
244 | static int __init do_ne2_probe(struct net_device *dev) | ||
245 | { | ||
246 | static int current_mca_slot = -1; | ||
247 | int i; | ||
248 | int adapter_found = 0; | ||
249 | |||
250 | /* Do not check any supplied i/o locations. | ||
251 | POS registers usually don't fail :) */ | ||
252 | |||
253 | /* MCA cards have POS registers. | ||
254 | Autodetecting MCA cards is extremely simple. | ||
255 | Just search for the card. */ | ||
256 | |||
257 | for(i = 0; (ne2_adapters[i].name != NULL) && !adapter_found; i++) { | ||
258 | current_mca_slot = | ||
259 | mca_find_unused_adapter(ne2_adapters[i].id, 0); | ||
260 | |||
261 | if((current_mca_slot != MCA_NOTFOUND) && !adapter_found) { | ||
262 | int res; | ||
263 | mca_set_adapter_name(current_mca_slot, | ||
264 | ne2_adapters[i].name); | ||
265 | mca_mark_as_used(current_mca_slot); | ||
266 | |||
267 | res = ne2_probe1(dev, current_mca_slot); | ||
268 | if (res) | ||
269 | mca_mark_as_unused(current_mca_slot); | ||
270 | return res; | ||
271 | } | ||
272 | } | ||
273 | return -ENODEV; | ||
274 | } | ||
275 | |||
276 | #ifndef MODULE | ||
277 | struct net_device * __init ne2_probe(int unit) | ||
278 | { | ||
279 | struct net_device *dev = alloc_eip_netdev(); | ||
280 | int err; | ||
281 | |||
282 | if (!dev) | ||
283 | return ERR_PTR(-ENOMEM); | ||
284 | |||
285 | sprintf(dev->name, "eth%d", unit); | ||
286 | netdev_boot_setup_check(dev); | ||
287 | |||
288 | err = do_ne2_probe(dev); | ||
289 | if (err) | ||
290 | goto out; | ||
291 | return dev; | ||
292 | out: | ||
293 | free_netdev(dev); | ||
294 | return ERR_PTR(err); | ||
295 | } | ||
296 | #endif | ||
297 | |||
298 | static int ne2_procinfo(char *buf, int slot, struct net_device *dev) | ||
299 | { | ||
300 | int len=0; | ||
301 | |||
302 | len += sprintf(buf+len, "The NE/2 Ethernet Adapter\n" ); | ||
303 | len += sprintf(buf+len, "Driver written by Wim Dumon "); | ||
304 | len += sprintf(buf+len, "<wimpie@kotnet.org>\n"); | ||
305 | len += sprintf(buf+len, "Modified by "); | ||
306 | len += sprintf(buf+len, "David Weinehall <tao@acc.umu.se>\n"); | ||
307 | len += sprintf(buf+len, "and by Magnus Jonsson <bigfoot@acc.umu.se>\n"); | ||
308 | len += sprintf(buf+len, "Based on the original NE2000 drivers\n" ); | ||
309 | len += sprintf(buf+len, "Base IO: %#x\n", (unsigned int)dev->base_addr); | ||
310 | len += sprintf(buf+len, "IRQ : %d\n", dev->irq); | ||
311 | len += sprintf(buf+len, "HW addr : %pM\n", dev->dev_addr); | ||
312 | |||
313 | return len; | ||
314 | } | ||
315 | |||
316 | static int __init ne2_probe1(struct net_device *dev, int slot) | ||
317 | { | ||
318 | int i, base_addr, irq, retval; | ||
319 | unsigned char POS; | ||
320 | unsigned char SA_prom[32]; | ||
321 | const char *name = "NE/2"; | ||
322 | int start_page, stop_page; | ||
323 | static unsigned version_printed; | ||
324 | |||
325 | if (ei_debug && version_printed++ == 0) | ||
326 | printk(version); | ||
327 | |||
328 | printk("NE/2 ethercard found in slot %d:", slot); | ||
329 | |||
330 | /* Read base IO and IRQ from the POS-registers */ | ||
331 | POS = mca_read_stored_pos(slot, 2); | ||
332 | if(!(POS % 2)) { | ||
333 | printk(" disabled.\n"); | ||
334 | return -ENODEV; | ||
335 | } | ||
336 | |||
337 | /* handle different POS register structure for D-Link card */ | ||
338 | |||
339 | if (mca_read_stored_pos(slot, 0) == 0xea) { | ||
340 | base_addr = dlink_addresses[(POS >> 5) & 0x03]; | ||
341 | irq = dlink_irqs[(POS >> 2) & 0x07]; | ||
342 | } | ||
343 | else { | ||
344 | i = (POS & 0xE)>>1; | ||
345 | /* printk("Halleluja sdog, als er na de pijl een 1 staat is 1 - 1 == 0" | ||
346 | " en zou het moeten werken -> %d\n", i); | ||
347 | The above line was for remote testing, thanx to sdog ... */ | ||
348 | base_addr = addresses[i - 1]; | ||
349 | irq = irqs[(POS & 0x60)>>5]; | ||
350 | } | ||
351 | |||
352 | if (!request_region(base_addr, NE_IO_EXTENT, DRV_NAME)) | ||
353 | return -EBUSY; | ||
354 | |||
355 | #ifdef DEBUG | ||
356 | printk("POS info : pos 2 = %#x ; base = %#x ; irq = %ld\n", POS, | ||
357 | base_addr, irq); | ||
358 | #endif | ||
359 | |||
360 | #ifndef CRYNWR_WAY | ||
361 | /* Reset the card the way they do it in the Crynwr packet driver */ | ||
362 | for (i=0; i<8; i++) | ||
363 | outb(0x0, base_addr + NE_RESET); | ||
364 | inb(base_addr + NE_RESET); | ||
365 | outb(0x21, base_addr + NE_CMD); | ||
366 | if (inb(base_addr + NE_CMD) != 0x21) { | ||
367 | printk("NE/2 adapter not responding\n"); | ||
368 | retval = -ENODEV; | ||
369 | goto out; | ||
370 | } | ||
371 | |||
372 | /* In the crynwr sources they do a RAM-test here. I skip it. I suppose | ||
373 | my RAM is okay. Suppose your memory is broken. Then this test | ||
374 | should fail and you won't be able to use your card. But if I do not | ||
375 | test, you won't be able to use your card, neither. So this test | ||
376 | won't help you. */ | ||
377 | |||
378 | #else /* _I_ never tested it this way .. Go ahead and try ...*/ | ||
379 | /* Reset card. Who knows what dain-bramaged state it was left in. */ | ||
380 | { | ||
381 | unsigned long reset_start_time = jiffies; | ||
382 | |||
383 | /* DON'T change these to inb_p/outb_p or reset will fail on | ||
384 | clones.. */ | ||
385 | outb(inb(base_addr + NE_RESET), base_addr + NE_RESET); | ||
386 | |||
387 | while ((inb_p(base_addr + EN0_ISR) & ENISR_RESET) == 0) | ||
388 | if (time_after(jiffies, reset_start_time + 2*HZ/100)) { | ||
389 | printk(" not found (no reset ack).\n"); | ||
390 | retval = -ENODEV; | ||
391 | goto out; | ||
392 | } | ||
393 | |||
394 | outb_p(0xff, base_addr + EN0_ISR); /* Ack all intr. */ | ||
395 | } | ||
396 | #endif | ||
397 | |||
398 | |||
399 | /* Read the 16 bytes of station address PROM. | ||
400 | We must first initialize registers, similar to | ||
401 | NS8390p_init(eifdev, 0). | ||
402 | We can't reliably read the SAPROM address without this. | ||
403 | (I learned the hard way!). */ | ||
404 | { | ||
405 | struct { | ||
406 | unsigned char value, offset; | ||
407 | } program_seq[] = { | ||
408 | /* Select page 0 */ | ||
409 | {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, | ||
410 | {0x49, EN0_DCFG}, /* Set WORD-wide (0x49) access. */ | ||
411 | {0x00, EN0_RCNTLO}, /* Clear the count regs. */ | ||
412 | {0x00, EN0_RCNTHI}, | ||
413 | {0x00, EN0_IMR}, /* Mask completion irq. */ | ||
414 | {0xFF, EN0_ISR}, | ||
415 | {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ | ||
416 | {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ | ||
417 | {32, EN0_RCNTLO}, | ||
418 | {0x00, EN0_RCNTHI}, | ||
419 | {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ | ||
420 | {0x00, EN0_RSARHI}, | ||
421 | {E8390_RREAD+E8390_START, E8390_CMD}, | ||
422 | }; | ||
423 | |||
424 | for (i = 0; i < ARRAY_SIZE(program_seq); i++) | ||
425 | outb_p(program_seq[i].value, base_addr + | ||
426 | program_seq[i].offset); | ||
427 | |||
428 | } | ||
429 | for(i = 0; i < 6 /*sizeof(SA_prom)*/; i+=1) { | ||
430 | SA_prom[i] = inb(base_addr + NE_DATAPORT); | ||
431 | } | ||
432 | |||
433 | /* I don't know whether the previous sequence includes the general | ||
434 | board reset procedure, so better don't omit it and just overwrite | ||
435 | the garbage read from a DE-320 with correct stuff. */ | ||
436 | |||
437 | if (mca_read_stored_pos(slot, 0) == 0xea) { | ||
438 | unsigned int v; | ||
439 | |||
440 | for (i = 0; i < 3; i++) { | ||
441 | v = dlink_get_eeprom(i, base_addr); | ||
442 | SA_prom[(i << 1) ] = v & 0xff; | ||
443 | SA_prom[(i << 1) + 1] = (v >> 8) & 0xff; | ||
444 | } | ||
445 | } | ||
446 | |||
447 | start_page = NESM_START_PG; | ||
448 | stop_page = NESM_STOP_PG; | ||
449 | |||
450 | dev->irq=irq; | ||
451 | |||
452 | /* Snarf the interrupt now. There's no point in waiting since we cannot | ||
453 | share and the board will usually be enabled. */ | ||
454 | retval = request_irq(dev->irq, eip_interrupt, 0, DRV_NAME, dev); | ||
455 | if (retval) { | ||
456 | printk (" unable to get IRQ %d (irqval=%d).\n", | ||
457 | dev->irq, retval); | ||
458 | goto out; | ||
459 | } | ||
460 | |||
461 | dev->base_addr = base_addr; | ||
462 | |||
463 | for(i = 0; i < ETHER_ADDR_LEN; i++) | ||
464 | dev->dev_addr[i] = SA_prom[i]; | ||
465 | |||
466 | printk(" %pM\n", dev->dev_addr); | ||
467 | |||
468 | printk("%s: %s found at %#x, using IRQ %d.\n", | ||
469 | dev->name, name, base_addr, dev->irq); | ||
470 | |||
471 | mca_set_adapter_procfn(slot, (MCA_ProcFn) ne2_procinfo, dev); | ||
472 | |||
473 | ei_status.name = name; | ||
474 | ei_status.tx_start_page = start_page; | ||
475 | ei_status.stop_page = stop_page; | ||
476 | ei_status.word16 = (2 == 2); | ||
477 | |||
478 | ei_status.rx_start_page = start_page + TX_PAGES; | ||
479 | #ifdef PACKETBUF_MEMSIZE | ||
480 | /* Allow the packet buffer size to be overridden by know-it-alls. */ | ||
481 | ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; | ||
482 | #endif | ||
483 | |||
484 | ei_status.reset_8390 = &ne_reset_8390; | ||
485 | ei_status.block_input = &ne_block_input; | ||
486 | ei_status.block_output = &ne_block_output; | ||
487 | ei_status.get_8390_hdr = &ne_get_8390_hdr; | ||
488 | |||
489 | ei_status.priv = slot; | ||
490 | |||
491 | dev->netdev_ops = &eip_netdev_ops; | ||
492 | NS8390p_init(dev, 0); | ||
493 | |||
494 | retval = register_netdev(dev); | ||
495 | if (retval) | ||
496 | goto out1; | ||
497 | return 0; | ||
498 | out1: | ||
499 | mca_set_adapter_procfn( ei_status.priv, NULL, NULL); | ||
500 | free_irq(dev->irq, dev); | ||
501 | out: | ||
502 | release_region(base_addr, NE_IO_EXTENT); | ||
503 | return retval; | ||
504 | } | ||
505 | |||
506 | /* Hard reset the card. This used to pause for the same period that a | ||
507 | 8390 reset command required, but that shouldn't be necessary. */ | ||
508 | static void ne_reset_8390(struct net_device *dev) | ||
509 | { | ||
510 | unsigned long reset_start_time = jiffies; | ||
511 | |||
512 | if (ei_debug > 1) | ||
513 | printk("resetting the 8390 t=%ld...", jiffies); | ||
514 | |||
515 | /* DON'T change these to inb_p/outb_p or reset will fail on clones. */ | ||
516 | outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); | ||
517 | |||
518 | ei_status.txing = 0; | ||
519 | ei_status.dmaing = 0; | ||
520 | |||
521 | /* This check _should_not_ be necessary, omit eventually. */ | ||
522 | while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) | ||
523 | if (time_after(jiffies, reset_start_time + 2*HZ/100)) { | ||
524 | printk("%s: ne_reset_8390() did not complete.\n", | ||
525 | dev->name); | ||
526 | break; | ||
527 | } | ||
528 | outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ | ||
529 | } | ||
530 | |||
531 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
532 | we don't need to be concerned with ring wrap as the header will be at | ||
533 | the start of a page, so we optimize accordingly. */ | ||
534 | |||
535 | static void ne_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
536 | int ring_page) | ||
537 | { | ||
538 | |||
539 | int nic_base = dev->base_addr; | ||
540 | |||
541 | /* This *shouldn't* happen. | ||
542 | If it does, it's the last thing you'll see */ | ||
543 | if (ei_status.dmaing) { | ||
544 | printk("%s: DMAing conflict in ne_get_8390_hdr " | ||
545 | "[DMAstat:%d][irqlock:%d].\n", | ||
546 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
547 | return; | ||
548 | } | ||
549 | |||
550 | ei_status.dmaing |= 0x01; | ||
551 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); | ||
552 | outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); | ||
553 | outb_p(0, nic_base + EN0_RCNTHI); | ||
554 | outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ | ||
555 | outb_p(ring_page, nic_base + EN0_RSARHI); | ||
556 | outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
557 | |||
558 | if (ei_status.word16) | ||
559 | insw(NE_BASE + NE_DATAPORT, hdr, | ||
560 | sizeof(struct e8390_pkt_hdr)>>1); | ||
561 | else | ||
562 | insb(NE_BASE + NE_DATAPORT, hdr, | ||
563 | sizeof(struct e8390_pkt_hdr)); | ||
564 | |||
565 | outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
566 | ei_status.dmaing &= ~0x01; | ||
567 | } | ||
568 | |||
569 | /* Block input and output, similar to the Crynwr packet driver. If you | ||
570 | are porting to a new ethercard, look at the packet driver source for | ||
571 | hints. The NEx000 doesn't share the on-board packet memory -- you have | ||
572 | to put the packet out through the "remote DMA" dataport using outb. */ | ||
573 | |||
574 | static void ne_block_input(struct net_device *dev, int count, struct sk_buff *skb, | ||
575 | int ring_offset) | ||
576 | { | ||
577 | #ifdef NE_SANITY_CHECK | ||
578 | int xfer_count = count; | ||
579 | #endif | ||
580 | int nic_base = dev->base_addr; | ||
581 | char *buf = skb->data; | ||
582 | |||
583 | /* This *shouldn't* happen. | ||
584 | If it does, it's the last thing you'll see */ | ||
585 | if (ei_status.dmaing) { | ||
586 | printk("%s: DMAing conflict in ne_block_input " | ||
587 | "[DMAstat:%d][irqlock:%d].\n", | ||
588 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
589 | return; | ||
590 | } | ||
591 | ei_status.dmaing |= 0x01; | ||
592 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); | ||
593 | outb_p(count & 0xff, nic_base + EN0_RCNTLO); | ||
594 | outb_p(count >> 8, nic_base + EN0_RCNTHI); | ||
595 | outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); | ||
596 | outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); | ||
597 | outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
598 | if (ei_status.word16) { | ||
599 | insw(NE_BASE + NE_DATAPORT,buf,count>>1); | ||
600 | if (count & 0x01) { | ||
601 | buf[count-1] = inb(NE_BASE + NE_DATAPORT); | ||
602 | #ifdef NE_SANITY_CHECK | ||
603 | xfer_count++; | ||
604 | #endif | ||
605 | } | ||
606 | } else { | ||
607 | insb(NE_BASE + NE_DATAPORT, buf, count); | ||
608 | } | ||
609 | |||
610 | #ifdef NE_SANITY_CHECK | ||
611 | /* This was for the ALPHA version only, but enough people have | ||
612 | been encountering problems so it is still here. If you see | ||
613 | this message you either 1) have a slightly incompatible clone | ||
614 | or 2) have noise/speed problems with your bus. */ | ||
615 | if (ei_debug > 1) { /* DMA termination address check... */ | ||
616 | int addr, tries = 20; | ||
617 | do { | ||
618 | /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here | ||
619 | -- it's broken for Rx on some cards! */ | ||
620 | int high = inb_p(nic_base + EN0_RSARHI); | ||
621 | int low = inb_p(nic_base + EN0_RSARLO); | ||
622 | addr = (high << 8) + low; | ||
623 | if (((ring_offset + xfer_count) & 0xff) == low) | ||
624 | break; | ||
625 | } while (--tries > 0); | ||
626 | if (tries <= 0) | ||
627 | printk("%s: RX transfer address mismatch," | ||
628 | "%#4.4x (expected) vs. %#4.4x (actual).\n", | ||
629 | dev->name, ring_offset + xfer_count, addr); | ||
630 | } | ||
631 | #endif | ||
632 | outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
633 | ei_status.dmaing &= ~0x01; | ||
634 | } | ||
635 | |||
636 | static void ne_block_output(struct net_device *dev, int count, | ||
637 | const unsigned char *buf, const int start_page) | ||
638 | { | ||
639 | int nic_base = NE_BASE; | ||
640 | unsigned long dma_start; | ||
641 | #ifdef NE_SANITY_CHECK | ||
642 | int retries = 0; | ||
643 | #endif | ||
644 | |||
645 | /* Round the count up for word writes. Do we need to do this? | ||
646 | What effect will an odd byte count have on the 8390? | ||
647 | I should check someday. */ | ||
648 | if (ei_status.word16 && (count & 0x01)) | ||
649 | count++; | ||
650 | |||
651 | /* This *shouldn't* happen. | ||
652 | If it does, it's the last thing you'll see */ | ||
653 | if (ei_status.dmaing) { | ||
654 | printk("%s: DMAing conflict in ne_block_output." | ||
655 | "[DMAstat:%d][irqlock:%d]\n", | ||
656 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
657 | return; | ||
658 | } | ||
659 | ei_status.dmaing |= 0x01; | ||
660 | /* We should already be in page 0, but to be safe... */ | ||
661 | outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); | ||
662 | |||
663 | #ifdef NE_SANITY_CHECK | ||
664 | retry: | ||
665 | #endif | ||
666 | |||
667 | #ifdef NE8390_RW_BUGFIX | ||
668 | /* Handle the read-before-write bug the same way as the | ||
669 | Crynwr packet driver -- the NatSemi method doesn't work. | ||
670 | Actually this doesn't always work either, but if you have | ||
671 | problems with your NEx000 this is better than nothing! */ | ||
672 | outb_p(0x42, nic_base + EN0_RCNTLO); | ||
673 | outb_p(0x00, nic_base + EN0_RCNTHI); | ||
674 | outb_p(0x42, nic_base + EN0_RSARLO); | ||
675 | outb_p(0x00, nic_base + EN0_RSARHI); | ||
676 | outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
677 | /* Make certain that the dummy read has occurred. */ | ||
678 | SLOW_DOWN_IO; | ||
679 | SLOW_DOWN_IO; | ||
680 | SLOW_DOWN_IO; | ||
681 | #endif | ||
682 | |||
683 | outb_p(ENISR_RDC, nic_base + EN0_ISR); | ||
684 | |||
685 | /* Now the normal output. */ | ||
686 | outb_p(count & 0xff, nic_base + EN0_RCNTLO); | ||
687 | outb_p(count >> 8, nic_base + EN0_RCNTHI); | ||
688 | outb_p(0x00, nic_base + EN0_RSARLO); | ||
689 | outb_p(start_page, nic_base + EN0_RSARHI); | ||
690 | |||
691 | outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD); | ||
692 | if (ei_status.word16) { | ||
693 | outsw(NE_BASE + NE_DATAPORT, buf, count>>1); | ||
694 | } else { | ||
695 | outsb(NE_BASE + NE_DATAPORT, buf, count); | ||
696 | } | ||
697 | |||
698 | dma_start = jiffies; | ||
699 | |||
700 | #ifdef NE_SANITY_CHECK | ||
701 | /* This was for the ALPHA version only, but enough people have | ||
702 | been encountering problems so it is still here. */ | ||
703 | |||
704 | if (ei_debug > 1) { /* DMA termination address check... */ | ||
705 | int addr, tries = 20; | ||
706 | do { | ||
707 | int high = inb_p(nic_base + EN0_RSARHI); | ||
708 | int low = inb_p(nic_base + EN0_RSARLO); | ||
709 | addr = (high << 8) + low; | ||
710 | if ((start_page << 8) + count == addr) | ||
711 | break; | ||
712 | } while (--tries > 0); | ||
713 | if (tries <= 0) { | ||
714 | printk("%s: Tx packet transfer address mismatch," | ||
715 | "%#4.4x (expected) vs. %#4.4x (actual).\n", | ||
716 | dev->name, (start_page << 8) + count, addr); | ||
717 | if (retries++ == 0) | ||
718 | goto retry; | ||
719 | } | ||
720 | } | ||
721 | #endif | ||
722 | |||
723 | while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) | ||
724 | if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */ | ||
725 | printk("%s: timeout waiting for Tx RDC.\n", dev->name); | ||
726 | ne_reset_8390(dev); | ||
727 | NS8390p_init(dev, 1); | ||
728 | break; | ||
729 | } | ||
730 | |||
731 | outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
732 | ei_status.dmaing &= ~0x01; | ||
733 | } | ||
734 | |||
735 | |||
736 | #ifdef MODULE | ||
737 | #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ | ||
738 | static struct net_device *dev_ne[MAX_NE_CARDS]; | ||
739 | static int io[MAX_NE_CARDS]; | ||
740 | static int irq[MAX_NE_CARDS]; | ||
741 | static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */ | ||
742 | MODULE_LICENSE("GPL"); | ||
743 | |||
744 | module_param_array(io, int, NULL, 0); | ||
745 | module_param_array(irq, int, NULL, 0); | ||
746 | module_param_array(bad, int, NULL, 0); | ||
747 | MODULE_PARM_DESC(io, "(ignored)"); | ||
748 | MODULE_PARM_DESC(irq, "(ignored)"); | ||
749 | MODULE_PARM_DESC(bad, "(ignored)"); | ||
750 | |||
751 | /* Module code fixed by David Weinehall */ | ||
752 | |||
753 | int __init init_module(void) | ||
754 | { | ||
755 | struct net_device *dev; | ||
756 | int this_dev, found = 0; | ||
757 | |||
758 | for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { | ||
759 | dev = alloc_eip_netdev(); | ||
760 | if (!dev) | ||
761 | break; | ||
762 | dev->irq = irq[this_dev]; | ||
763 | dev->mem_end = bad[this_dev]; | ||
764 | dev->base_addr = io[this_dev]; | ||
765 | if (do_ne2_probe(dev) == 0) { | ||
766 | dev_ne[found++] = dev; | ||
767 | continue; | ||
768 | } | ||
769 | free_netdev(dev); | ||
770 | break; | ||
771 | } | ||
772 | if (found) | ||
773 | return 0; | ||
774 | printk(KERN_WARNING "ne2.c: No NE/2 card found\n"); | ||
775 | return -ENXIO; | ||
776 | } | ||
777 | |||
778 | static void cleanup_card(struct net_device *dev) | ||
779 | { | ||
780 | mca_mark_as_unused(ei_status.priv); | ||
781 | mca_set_adapter_procfn( ei_status.priv, NULL, NULL); | ||
782 | free_irq(dev->irq, dev); | ||
783 | release_region(dev->base_addr, NE_IO_EXTENT); | ||
784 | } | ||
785 | |||
786 | void __exit cleanup_module(void) | ||
787 | { | ||
788 | int this_dev; | ||
789 | |||
790 | for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { | ||
791 | struct net_device *dev = dev_ne[this_dev]; | ||
792 | if (dev) { | ||
793 | unregister_netdev(dev); | ||
794 | cleanup_card(dev); | ||
795 | free_netdev(dev); | ||
796 | } | ||
797 | } | ||
798 | } | ||
799 | #endif /* MODULE */ | ||
diff --git a/drivers/net/ethernet/8390/ne2k-pci.c b/drivers/net/ethernet/8390/ne2k-pci.c new file mode 100644 index 000000000000..3c333cb5d34e --- /dev/null +++ b/drivers/net/ethernet/8390/ne2k-pci.c | |||
@@ -0,0 +1,726 @@ | |||
1 | /* ne2k-pci.c: A NE2000 clone on PCI bus driver for Linux. */ | ||
2 | /* | ||
3 | A Linux device driver for PCI NE2000 clones. | ||
4 | |||
5 | Authors and other copyright holders: | ||
6 | 1992-2000 by Donald Becker, NE2000 core and various modifications. | ||
7 | 1995-1998 by Paul Gortmaker, core modifications and PCI support. | ||
8 | Copyright 1993 assigned to the United States Government as represented | ||
9 | by the Director, National Security Agency. | ||
10 | |||
11 | This software may be used and distributed according to the terms of | ||
12 | the GNU General Public License (GPL), incorporated herein by reference. | ||
13 | Drivers based on or derived from this code fall under the GPL and must | ||
14 | retain the authorship, copyright and license notice. This file is not | ||
15 | a complete program and may only be used when the entire operating | ||
16 | system is licensed under the GPL. | ||
17 | |||
18 | The author may be reached as becker@scyld.com, or C/O | ||
19 | Scyld Computing Corporation | ||
20 | 410 Severn Ave., Suite 210 | ||
21 | Annapolis MD 21403 | ||
22 | |||
23 | Issues remaining: | ||
24 | People are making PCI ne2000 clones! Oh the horror, the horror... | ||
25 | Limited full-duplex support. | ||
26 | */ | ||
27 | |||
28 | #define DRV_NAME "ne2k-pci" | ||
29 | #define DRV_VERSION "1.03" | ||
30 | #define DRV_RELDATE "9/22/2003" | ||
31 | |||
32 | |||
33 | /* The user-configurable values. | ||
34 | These may be modified when a driver module is loaded.*/ | ||
35 | |||
36 | static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ | ||
37 | |||
38 | #define MAX_UNITS 8 /* More are supported, limit only on options */ | ||
39 | /* Used to pass the full-duplex flag, etc. */ | ||
40 | static int full_duplex[MAX_UNITS]; | ||
41 | static int options[MAX_UNITS]; | ||
42 | |||
43 | /* Force a non std. amount of memory. Units are 256 byte pages. */ | ||
44 | /* #define PACKETBUF_MEMSIZE 0x40 */ | ||
45 | |||
46 | |||
47 | #include <linux/module.h> | ||
48 | #include <linux/kernel.h> | ||
49 | #include <linux/errno.h> | ||
50 | #include <linux/pci.h> | ||
51 | #include <linux/init.h> | ||
52 | #include <linux/interrupt.h> | ||
53 | #include <linux/ethtool.h> | ||
54 | #include <linux/netdevice.h> | ||
55 | #include <linux/etherdevice.h> | ||
56 | |||
57 | #include <asm/system.h> | ||
58 | #include <asm/io.h> | ||
59 | #include <asm/irq.h> | ||
60 | #include <asm/uaccess.h> | ||
61 | |||
62 | #include "8390.h" | ||
63 | |||
64 | /* These identify the driver base version and may not be removed. */ | ||
65 | static const char version[] __devinitconst = | ||
66 | KERN_INFO DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE | ||
67 | " D. Becker/P. Gortmaker\n"; | ||
68 | |||
69 | #if defined(__powerpc__) | ||
70 | #define inl_le(addr) le32_to_cpu(inl(addr)) | ||
71 | #define inw_le(addr) le16_to_cpu(inw(addr)) | ||
72 | #endif | ||
73 | |||
74 | #define PFX DRV_NAME ": " | ||
75 | |||
76 | MODULE_AUTHOR("Donald Becker / Paul Gortmaker"); | ||
77 | MODULE_DESCRIPTION("PCI NE2000 clone driver"); | ||
78 | MODULE_LICENSE("GPL"); | ||
79 | |||
80 | module_param(debug, int, 0); | ||
81 | module_param_array(options, int, NULL, 0); | ||
82 | module_param_array(full_duplex, int, NULL, 0); | ||
83 | MODULE_PARM_DESC(debug, "debug level (1-2)"); | ||
84 | MODULE_PARM_DESC(options, "Bit 5: full duplex"); | ||
85 | MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)"); | ||
86 | |||
87 | /* Some defines that people can play with if so inclined. */ | ||
88 | |||
89 | /* Use 32 bit data-movement operations instead of 16 bit. */ | ||
90 | #define USE_LONGIO | ||
91 | |||
92 | /* Do we implement the read before write bugfix ? */ | ||
93 | /* #define NE_RW_BUGFIX */ | ||
94 | |||
95 | /* Flags. We rename an existing ei_status field to store flags! */ | ||
96 | /* Thus only the low 8 bits are usable for non-init-time flags. */ | ||
97 | #define ne2k_flags reg0 | ||
98 | enum { | ||
99 | ONLY_16BIT_IO=8, ONLY_32BIT_IO=4, /* Chip can do only 16/32-bit xfers. */ | ||
100 | FORCE_FDX=0x20, /* User override. */ | ||
101 | REALTEK_FDX=0x40, HOLTEK_FDX=0x80, | ||
102 | STOP_PG_0x60=0x100, | ||
103 | }; | ||
104 | |||
105 | enum ne2k_pci_chipsets { | ||
106 | CH_RealTek_RTL_8029 = 0, | ||
107 | CH_Winbond_89C940, | ||
108 | CH_Compex_RL2000, | ||
109 | CH_KTI_ET32P2, | ||
110 | CH_NetVin_NV5000SC, | ||
111 | CH_Via_86C926, | ||
112 | CH_SureCom_NE34, | ||
113 | CH_Winbond_W89C940F, | ||
114 | CH_Holtek_HT80232, | ||
115 | CH_Holtek_HT80229, | ||
116 | CH_Winbond_89C940_8c4a, | ||
117 | }; | ||
118 | |||
119 | |||
120 | static struct { | ||
121 | char *name; | ||
122 | int flags; | ||
123 | } pci_clone_list[] __devinitdata = { | ||
124 | {"RealTek RTL-8029", REALTEK_FDX}, | ||
125 | {"Winbond 89C940", 0}, | ||
126 | {"Compex RL2000", 0}, | ||
127 | {"KTI ET32P2", 0}, | ||
128 | {"NetVin NV5000SC", 0}, | ||
129 | {"Via 86C926", ONLY_16BIT_IO}, | ||
130 | {"SureCom NE34", 0}, | ||
131 | {"Winbond W89C940F", 0}, | ||
132 | {"Holtek HT80232", ONLY_16BIT_IO | HOLTEK_FDX}, | ||
133 | {"Holtek HT80229", ONLY_32BIT_IO | HOLTEK_FDX | STOP_PG_0x60 }, | ||
134 | {"Winbond W89C940(misprogrammed)", 0}, | ||
135 | {NULL,} | ||
136 | }; | ||
137 | |||
138 | |||
139 | static DEFINE_PCI_DEVICE_TABLE(ne2k_pci_tbl) = { | ||
140 | { 0x10ec, 0x8029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_RealTek_RTL_8029 }, | ||
141 | { 0x1050, 0x0940, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940 }, | ||
142 | { 0x11f6, 0x1401, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Compex_RL2000 }, | ||
143 | { 0x8e2e, 0x3000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_KTI_ET32P2 }, | ||
144 | { 0x4a14, 0x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_NetVin_NV5000SC }, | ||
145 | { 0x1106, 0x0926, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Via_86C926 }, | ||
146 | { 0x10bd, 0x0e34, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_SureCom_NE34 }, | ||
147 | { 0x1050, 0x5a5a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_W89C940F }, | ||
148 | { 0x12c3, 0x0058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80232 }, | ||
149 | { 0x12c3, 0x5598, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Holtek_HT80229 }, | ||
150 | { 0x8c4a, 0x1980, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_Winbond_89C940_8c4a }, | ||
151 | { 0, } | ||
152 | }; | ||
153 | MODULE_DEVICE_TABLE(pci, ne2k_pci_tbl); | ||
154 | |||
155 | |||
156 | /* ---- No user-serviceable parts below ---- */ | ||
157 | |||
158 | #define NE_BASE (dev->base_addr) | ||
159 | #define NE_CMD 0x00 | ||
160 | #define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */ | ||
161 | #define NE_RESET 0x1f /* Issue a read to reset, a write to clear. */ | ||
162 | #define NE_IO_EXTENT 0x20 | ||
163 | |||
164 | #define NESM_START_PG 0x40 /* First page of TX buffer */ | ||
165 | #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
166 | |||
167 | |||
168 | static int ne2k_pci_open(struct net_device *dev); | ||
169 | static int ne2k_pci_close(struct net_device *dev); | ||
170 | |||
171 | static void ne2k_pci_reset_8390(struct net_device *dev); | ||
172 | static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
173 | int ring_page); | ||
174 | static void ne2k_pci_block_input(struct net_device *dev, int count, | ||
175 | struct sk_buff *skb, int ring_offset); | ||
176 | static void ne2k_pci_block_output(struct net_device *dev, const int count, | ||
177 | const unsigned char *buf, const int start_page); | ||
178 | static const struct ethtool_ops ne2k_pci_ethtool_ops; | ||
179 | |||
180 | |||
181 | |||
182 | /* There is no room in the standard 8390 structure for extra info we need, | ||
183 | so we build a meta/outer-wrapper structure.. */ | ||
184 | struct ne2k_pci_card { | ||
185 | struct net_device *dev; | ||
186 | struct pci_dev *pci_dev; | ||
187 | }; | ||
188 | |||
189 | |||
190 | |||
191 | /* | ||
192 | NEx000-clone boards have a Station Address (SA) PROM (SAPROM) in the packet | ||
193 | buffer memory space. By-the-spec NE2000 clones have 0x57,0x57 in bytes | ||
194 | 0x0e,0x0f of the SAPROM, while other supposed NE2000 clones must be | ||
195 | detected by their SA prefix. | ||
196 | |||
197 | Reading the SAPROM from a word-wide card with the 8390 set in byte-wide | ||
198 | mode results in doubled values, which can be detected and compensated for. | ||
199 | |||
200 | The probe is also responsible for initializing the card and filling | ||
201 | in the 'dev' and 'ei_status' structures. | ||
202 | */ | ||
203 | |||
204 | static const struct net_device_ops ne2k_netdev_ops = { | ||
205 | .ndo_open = ne2k_pci_open, | ||
206 | .ndo_stop = ne2k_pci_close, | ||
207 | .ndo_start_xmit = ei_start_xmit, | ||
208 | .ndo_tx_timeout = ei_tx_timeout, | ||
209 | .ndo_get_stats = ei_get_stats, | ||
210 | .ndo_set_multicast_list = ei_set_multicast_list, | ||
211 | .ndo_validate_addr = eth_validate_addr, | ||
212 | .ndo_set_mac_address = eth_mac_addr, | ||
213 | .ndo_change_mtu = eth_change_mtu, | ||
214 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
215 | .ndo_poll_controller = ei_poll, | ||
216 | #endif | ||
217 | }; | ||
218 | |||
219 | static int __devinit ne2k_pci_init_one (struct pci_dev *pdev, | ||
220 | const struct pci_device_id *ent) | ||
221 | { | ||
222 | struct net_device *dev; | ||
223 | int i; | ||
224 | unsigned char SA_prom[32]; | ||
225 | int start_page, stop_page; | ||
226 | int irq, reg0, chip_idx = ent->driver_data; | ||
227 | static unsigned int fnd_cnt; | ||
228 | long ioaddr; | ||
229 | int flags = pci_clone_list[chip_idx].flags; | ||
230 | |||
231 | /* when built into the kernel, we only print version if device is found */ | ||
232 | #ifndef MODULE | ||
233 | static int printed_version; | ||
234 | if (!printed_version++) | ||
235 | printk(version); | ||
236 | #endif | ||
237 | |||
238 | fnd_cnt++; | ||
239 | |||
240 | i = pci_enable_device (pdev); | ||
241 | if (i) | ||
242 | return i; | ||
243 | |||
244 | ioaddr = pci_resource_start (pdev, 0); | ||
245 | irq = pdev->irq; | ||
246 | |||
247 | if (!ioaddr || ((pci_resource_flags (pdev, 0) & IORESOURCE_IO) == 0)) { | ||
248 | dev_err(&pdev->dev, "no I/O resource at PCI BAR #0\n"); | ||
249 | return -ENODEV; | ||
250 | } | ||
251 | |||
252 | if (request_region (ioaddr, NE_IO_EXTENT, DRV_NAME) == NULL) { | ||
253 | dev_err(&pdev->dev, "I/O resource 0x%x @ 0x%lx busy\n", | ||
254 | NE_IO_EXTENT, ioaddr); | ||
255 | return -EBUSY; | ||
256 | } | ||
257 | |||
258 | reg0 = inb(ioaddr); | ||
259 | if (reg0 == 0xFF) | ||
260 | goto err_out_free_res; | ||
261 | |||
262 | /* Do a preliminary verification that we have a 8390. */ | ||
263 | { | ||
264 | int regd; | ||
265 | outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD); | ||
266 | regd = inb(ioaddr + 0x0d); | ||
267 | outb(0xff, ioaddr + 0x0d); | ||
268 | outb(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD); | ||
269 | inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */ | ||
270 | if (inb(ioaddr + EN0_COUNTER0) != 0) { | ||
271 | outb(reg0, ioaddr); | ||
272 | outb(regd, ioaddr + 0x0d); /* Restore the old values. */ | ||
273 | goto err_out_free_res; | ||
274 | } | ||
275 | } | ||
276 | |||
277 | /* Allocate net_device, dev->priv; fill in 8390 specific dev fields. */ | ||
278 | dev = alloc_ei_netdev(); | ||
279 | if (!dev) { | ||
280 | dev_err(&pdev->dev, "cannot allocate ethernet device\n"); | ||
281 | goto err_out_free_res; | ||
282 | } | ||
283 | dev->netdev_ops = &ne2k_netdev_ops; | ||
284 | |||
285 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
286 | |||
287 | /* Reset card. Who knows what dain-bramaged state it was left in. */ | ||
288 | { | ||
289 | unsigned long reset_start_time = jiffies; | ||
290 | |||
291 | outb(inb(ioaddr + NE_RESET), ioaddr + NE_RESET); | ||
292 | |||
293 | /* This looks like a horrible timing loop, but it should never take | ||
294 | more than a few cycles. | ||
295 | */ | ||
296 | while ((inb(ioaddr + EN0_ISR) & ENISR_RESET) == 0) | ||
297 | /* Limit wait: '2' avoids jiffy roll-over. */ | ||
298 | if (jiffies - reset_start_time > 2) { | ||
299 | dev_err(&pdev->dev, | ||
300 | "Card failure (no reset ack).\n"); | ||
301 | goto err_out_free_netdev; | ||
302 | } | ||
303 | |||
304 | outb(0xff, ioaddr + EN0_ISR); /* Ack all intr. */ | ||
305 | } | ||
306 | |||
307 | /* Read the 16 bytes of station address PROM. | ||
308 | We must first initialize registers, similar to NS8390_init(eifdev, 0). | ||
309 | We can't reliably read the SAPROM address without this. | ||
310 | (I learned the hard way!). */ | ||
311 | { | ||
312 | struct {unsigned char value, offset; } program_seq[] = { | ||
313 | {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ | ||
314 | {0x49, EN0_DCFG}, /* Set word-wide access. */ | ||
315 | {0x00, EN0_RCNTLO}, /* Clear the count regs. */ | ||
316 | {0x00, EN0_RCNTHI}, | ||
317 | {0x00, EN0_IMR}, /* Mask completion irq. */ | ||
318 | {0xFF, EN0_ISR}, | ||
319 | {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ | ||
320 | {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ | ||
321 | {32, EN0_RCNTLO}, | ||
322 | {0x00, EN0_RCNTHI}, | ||
323 | {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ | ||
324 | {0x00, EN0_RSARHI}, | ||
325 | {E8390_RREAD+E8390_START, E8390_CMD}, | ||
326 | }; | ||
327 | for (i = 0; i < ARRAY_SIZE(program_seq); i++) | ||
328 | outb(program_seq[i].value, ioaddr + program_seq[i].offset); | ||
329 | |||
330 | } | ||
331 | |||
332 | /* Note: all PCI cards have at least 16 bit access, so we don't have | ||
333 | to check for 8 bit cards. Most cards permit 32 bit access. */ | ||
334 | if (flags & ONLY_32BIT_IO) { | ||
335 | for (i = 0; i < 4 ; i++) | ||
336 | ((u32 *)SA_prom)[i] = le32_to_cpu(inl(ioaddr + NE_DATAPORT)); | ||
337 | } else | ||
338 | for(i = 0; i < 32 /*sizeof(SA_prom)*/; i++) | ||
339 | SA_prom[i] = inb(ioaddr + NE_DATAPORT); | ||
340 | |||
341 | /* We always set the 8390 registers for word mode. */ | ||
342 | outb(0x49, ioaddr + EN0_DCFG); | ||
343 | start_page = NESM_START_PG; | ||
344 | |||
345 | stop_page = flags & STOP_PG_0x60 ? 0x60 : NESM_STOP_PG; | ||
346 | |||
347 | /* Set up the rest of the parameters. */ | ||
348 | dev->irq = irq; | ||
349 | dev->base_addr = ioaddr; | ||
350 | pci_set_drvdata(pdev, dev); | ||
351 | |||
352 | ei_status.name = pci_clone_list[chip_idx].name; | ||
353 | ei_status.tx_start_page = start_page; | ||
354 | ei_status.stop_page = stop_page; | ||
355 | ei_status.word16 = 1; | ||
356 | ei_status.ne2k_flags = flags; | ||
357 | if (fnd_cnt < MAX_UNITS) { | ||
358 | if (full_duplex[fnd_cnt] > 0 || (options[fnd_cnt] & FORCE_FDX)) | ||
359 | ei_status.ne2k_flags |= FORCE_FDX; | ||
360 | } | ||
361 | |||
362 | ei_status.rx_start_page = start_page + TX_PAGES; | ||
363 | #ifdef PACKETBUF_MEMSIZE | ||
364 | /* Allow the packet buffer size to be overridden by know-it-alls. */ | ||
365 | ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE; | ||
366 | #endif | ||
367 | |||
368 | ei_status.reset_8390 = &ne2k_pci_reset_8390; | ||
369 | ei_status.block_input = &ne2k_pci_block_input; | ||
370 | ei_status.block_output = &ne2k_pci_block_output; | ||
371 | ei_status.get_8390_hdr = &ne2k_pci_get_8390_hdr; | ||
372 | ei_status.priv = (unsigned long) pdev; | ||
373 | |||
374 | dev->ethtool_ops = &ne2k_pci_ethtool_ops; | ||
375 | NS8390_init(dev, 0); | ||
376 | |||
377 | memcpy(dev->dev_addr, SA_prom, dev->addr_len); | ||
378 | memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); | ||
379 | |||
380 | i = register_netdev(dev); | ||
381 | if (i) | ||
382 | goto err_out_free_netdev; | ||
383 | |||
384 | printk("%s: %s found at %#lx, IRQ %d, %pM.\n", | ||
385 | dev->name, pci_clone_list[chip_idx].name, ioaddr, dev->irq, | ||
386 | dev->dev_addr); | ||
387 | |||
388 | return 0; | ||
389 | |||
390 | err_out_free_netdev: | ||
391 | free_netdev (dev); | ||
392 | err_out_free_res: | ||
393 | release_region (ioaddr, NE_IO_EXTENT); | ||
394 | pci_set_drvdata (pdev, NULL); | ||
395 | return -ENODEV; | ||
396 | |||
397 | } | ||
398 | |||
399 | /* | ||
400 | * Magic incantation sequence for full duplex on the supported cards. | ||
401 | */ | ||
402 | static inline int set_realtek_fdx(struct net_device *dev) | ||
403 | { | ||
404 | long ioaddr = dev->base_addr; | ||
405 | |||
406 | outb(0xC0 + E8390_NODMA, ioaddr + NE_CMD); /* Page 3 */ | ||
407 | outb(0xC0, ioaddr + 0x01); /* Enable writes to CONFIG3 */ | ||
408 | outb(0x40, ioaddr + 0x06); /* Enable full duplex */ | ||
409 | outb(0x00, ioaddr + 0x01); /* Disable writes to CONFIG3 */ | ||
410 | outb(E8390_PAGE0 + E8390_NODMA, ioaddr + NE_CMD); /* Page 0 */ | ||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | static inline int set_holtek_fdx(struct net_device *dev) | ||
415 | { | ||
416 | long ioaddr = dev->base_addr; | ||
417 | |||
418 | outb(inb(ioaddr + 0x20) | 0x80, ioaddr + 0x20); | ||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | static int ne2k_pci_set_fdx(struct net_device *dev) | ||
423 | { | ||
424 | if (ei_status.ne2k_flags & REALTEK_FDX) | ||
425 | return set_realtek_fdx(dev); | ||
426 | else if (ei_status.ne2k_flags & HOLTEK_FDX) | ||
427 | return set_holtek_fdx(dev); | ||
428 | |||
429 | return -EOPNOTSUPP; | ||
430 | } | ||
431 | |||
432 | static int ne2k_pci_open(struct net_device *dev) | ||
433 | { | ||
434 | int ret = request_irq(dev->irq, ei_interrupt, IRQF_SHARED, dev->name, dev); | ||
435 | if (ret) | ||
436 | return ret; | ||
437 | |||
438 | if (ei_status.ne2k_flags & FORCE_FDX) | ||
439 | ne2k_pci_set_fdx(dev); | ||
440 | |||
441 | ei_open(dev); | ||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | static int ne2k_pci_close(struct net_device *dev) | ||
446 | { | ||
447 | ei_close(dev); | ||
448 | free_irq(dev->irq, dev); | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | /* Hard reset the card. This used to pause for the same period that a | ||
453 | 8390 reset command required, but that shouldn't be necessary. */ | ||
454 | static void ne2k_pci_reset_8390(struct net_device *dev) | ||
455 | { | ||
456 | unsigned long reset_start_time = jiffies; | ||
457 | |||
458 | if (debug > 1) printk("%s: Resetting the 8390 t=%ld...", | ||
459 | dev->name, jiffies); | ||
460 | |||
461 | outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); | ||
462 | |||
463 | ei_status.txing = 0; | ||
464 | ei_status.dmaing = 0; | ||
465 | |||
466 | /* This check _should_not_ be necessary, omit eventually. */ | ||
467 | while ((inb(NE_BASE+EN0_ISR) & ENISR_RESET) == 0) | ||
468 | if (jiffies - reset_start_time > 2) { | ||
469 | printk("%s: ne2k_pci_reset_8390() did not complete.\n", dev->name); | ||
470 | break; | ||
471 | } | ||
472 | outb(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */ | ||
473 | } | ||
474 | |||
475 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
476 | we don't need to be concerned with ring wrap as the header will be at | ||
477 | the start of a page, so we optimize accordingly. */ | ||
478 | |||
479 | static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
480 | { | ||
481 | |||
482 | long nic_base = dev->base_addr; | ||
483 | |||
484 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
485 | if (ei_status.dmaing) { | ||
486 | printk("%s: DMAing conflict in ne2k_pci_get_8390_hdr " | ||
487 | "[DMAstat:%d][irqlock:%d].\n", | ||
488 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
489 | return; | ||
490 | } | ||
491 | |||
492 | ei_status.dmaing |= 0x01; | ||
493 | outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); | ||
494 | outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); | ||
495 | outb(0, nic_base + EN0_RCNTHI); | ||
496 | outb(0, nic_base + EN0_RSARLO); /* On page boundary */ | ||
497 | outb(ring_page, nic_base + EN0_RSARHI); | ||
498 | outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
499 | |||
500 | if (ei_status.ne2k_flags & ONLY_16BIT_IO) { | ||
501 | insw(NE_BASE + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1); | ||
502 | } else { | ||
503 | *(u32*)hdr = le32_to_cpu(inl(NE_BASE + NE_DATAPORT)); | ||
504 | le16_to_cpus(&hdr->count); | ||
505 | } | ||
506 | |||
507 | outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
508 | ei_status.dmaing &= ~0x01; | ||
509 | } | ||
510 | |||
511 | /* Block input and output, similar to the Crynwr packet driver. If you | ||
512 | are porting to a new ethercard, look at the packet driver source for hints. | ||
513 | The NEx000 doesn't share the on-board packet memory -- you have to put | ||
514 | the packet out through the "remote DMA" dataport using outb. */ | ||
515 | |||
516 | static void ne2k_pci_block_input(struct net_device *dev, int count, | ||
517 | struct sk_buff *skb, int ring_offset) | ||
518 | { | ||
519 | long nic_base = dev->base_addr; | ||
520 | char *buf = skb->data; | ||
521 | |||
522 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
523 | if (ei_status.dmaing) { | ||
524 | printk("%s: DMAing conflict in ne2k_pci_block_input " | ||
525 | "[DMAstat:%d][irqlock:%d].\n", | ||
526 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
527 | return; | ||
528 | } | ||
529 | ei_status.dmaing |= 0x01; | ||
530 | if (ei_status.ne2k_flags & ONLY_32BIT_IO) | ||
531 | count = (count + 3) & 0xFFFC; | ||
532 | outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD); | ||
533 | outb(count & 0xff, nic_base + EN0_RCNTLO); | ||
534 | outb(count >> 8, nic_base + EN0_RCNTHI); | ||
535 | outb(ring_offset & 0xff, nic_base + EN0_RSARLO); | ||
536 | outb(ring_offset >> 8, nic_base + EN0_RSARHI); | ||
537 | outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
538 | |||
539 | if (ei_status.ne2k_flags & ONLY_16BIT_IO) { | ||
540 | insw(NE_BASE + NE_DATAPORT,buf,count>>1); | ||
541 | if (count & 0x01) { | ||
542 | buf[count-1] = inb(NE_BASE + NE_DATAPORT); | ||
543 | } | ||
544 | } else { | ||
545 | insl(NE_BASE + NE_DATAPORT, buf, count>>2); | ||
546 | if (count & 3) { | ||
547 | buf += count & ~3; | ||
548 | if (count & 2) { | ||
549 | __le16 *b = (__le16 *)buf; | ||
550 | |||
551 | *b++ = cpu_to_le16(inw(NE_BASE + NE_DATAPORT)); | ||
552 | buf = (char *)b; | ||
553 | } | ||
554 | if (count & 1) | ||
555 | *buf = inb(NE_BASE + NE_DATAPORT); | ||
556 | } | ||
557 | } | ||
558 | |||
559 | outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
560 | ei_status.dmaing &= ~0x01; | ||
561 | } | ||
562 | |||
563 | static void ne2k_pci_block_output(struct net_device *dev, int count, | ||
564 | const unsigned char *buf, const int start_page) | ||
565 | { | ||
566 | long nic_base = NE_BASE; | ||
567 | unsigned long dma_start; | ||
568 | |||
569 | /* On little-endian it's always safe to round the count up for | ||
570 | word writes. */ | ||
571 | if (ei_status.ne2k_flags & ONLY_32BIT_IO) | ||
572 | count = (count + 3) & 0xFFFC; | ||
573 | else | ||
574 | if (count & 0x01) | ||
575 | count++; | ||
576 | |||
577 | /* This *shouldn't* happen. If it does, it's the last thing you'll see */ | ||
578 | if (ei_status.dmaing) { | ||
579 | printk("%s: DMAing conflict in ne2k_pci_block_output." | ||
580 | "[DMAstat:%d][irqlock:%d]\n", | ||
581 | dev->name, ei_status.dmaing, ei_status.irqlock); | ||
582 | return; | ||
583 | } | ||
584 | ei_status.dmaing |= 0x01; | ||
585 | /* We should already be in page 0, but to be safe... */ | ||
586 | outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); | ||
587 | |||
588 | #ifdef NE8390_RW_BUGFIX | ||
589 | /* Handle the read-before-write bug the same way as the | ||
590 | Crynwr packet driver -- the NatSemi method doesn't work. | ||
591 | Actually this doesn't always work either, but if you have | ||
592 | problems with your NEx000 this is better than nothing! */ | ||
593 | outb(0x42, nic_base + EN0_RCNTLO); | ||
594 | outb(0x00, nic_base + EN0_RCNTHI); | ||
595 | outb(0x42, nic_base + EN0_RSARLO); | ||
596 | outb(0x00, nic_base + EN0_RSARHI); | ||
597 | outb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
598 | #endif | ||
599 | outb(ENISR_RDC, nic_base + EN0_ISR); | ||
600 | |||
601 | /* Now the normal output. */ | ||
602 | outb(count & 0xff, nic_base + EN0_RCNTLO); | ||
603 | outb(count >> 8, nic_base + EN0_RCNTHI); | ||
604 | outb(0x00, nic_base + EN0_RSARLO); | ||
605 | outb(start_page, nic_base + EN0_RSARHI); | ||
606 | outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD); | ||
607 | if (ei_status.ne2k_flags & ONLY_16BIT_IO) { | ||
608 | outsw(NE_BASE + NE_DATAPORT, buf, count>>1); | ||
609 | } else { | ||
610 | outsl(NE_BASE + NE_DATAPORT, buf, count>>2); | ||
611 | if (count & 3) { | ||
612 | buf += count & ~3; | ||
613 | if (count & 2) { | ||
614 | __le16 *b = (__le16 *)buf; | ||
615 | |||
616 | outw(le16_to_cpu(*b++), NE_BASE + NE_DATAPORT); | ||
617 | buf = (char *)b; | ||
618 | } | ||
619 | } | ||
620 | } | ||
621 | |||
622 | dma_start = jiffies; | ||
623 | |||
624 | while ((inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) | ||
625 | if (jiffies - dma_start > 2) { /* Avoid clock roll-over. */ | ||
626 | printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name); | ||
627 | ne2k_pci_reset_8390(dev); | ||
628 | NS8390_init(dev,1); | ||
629 | break; | ||
630 | } | ||
631 | |||
632 | outb(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
633 | ei_status.dmaing &= ~0x01; | ||
634 | } | ||
635 | |||
636 | static void ne2k_pci_get_drvinfo(struct net_device *dev, | ||
637 | struct ethtool_drvinfo *info) | ||
638 | { | ||
639 | struct ei_device *ei = netdev_priv(dev); | ||
640 | struct pci_dev *pci_dev = (struct pci_dev *) ei->priv; | ||
641 | |||
642 | strcpy(info->driver, DRV_NAME); | ||
643 | strcpy(info->version, DRV_VERSION); | ||
644 | strcpy(info->bus_info, pci_name(pci_dev)); | ||
645 | } | ||
646 | |||
647 | static const struct ethtool_ops ne2k_pci_ethtool_ops = { | ||
648 | .get_drvinfo = ne2k_pci_get_drvinfo, | ||
649 | }; | ||
650 | |||
651 | static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev) | ||
652 | { | ||
653 | struct net_device *dev = pci_get_drvdata(pdev); | ||
654 | |||
655 | BUG_ON(!dev); | ||
656 | unregister_netdev(dev); | ||
657 | release_region(dev->base_addr, NE_IO_EXTENT); | ||
658 | free_netdev(dev); | ||
659 | pci_disable_device(pdev); | ||
660 | pci_set_drvdata(pdev, NULL); | ||
661 | } | ||
662 | |||
663 | #ifdef CONFIG_PM | ||
664 | static int ne2k_pci_suspend (struct pci_dev *pdev, pm_message_t state) | ||
665 | { | ||
666 | struct net_device *dev = pci_get_drvdata (pdev); | ||
667 | |||
668 | netif_device_detach(dev); | ||
669 | pci_save_state(pdev); | ||
670 | pci_disable_device(pdev); | ||
671 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
672 | |||
673 | return 0; | ||
674 | } | ||
675 | |||
676 | static int ne2k_pci_resume (struct pci_dev *pdev) | ||
677 | { | ||
678 | struct net_device *dev = pci_get_drvdata (pdev); | ||
679 | int rc; | ||
680 | |||
681 | pci_set_power_state(pdev, 0); | ||
682 | pci_restore_state(pdev); | ||
683 | |||
684 | rc = pci_enable_device(pdev); | ||
685 | if (rc) | ||
686 | return rc; | ||
687 | |||
688 | NS8390_init(dev, 1); | ||
689 | netif_device_attach(dev); | ||
690 | |||
691 | return 0; | ||
692 | } | ||
693 | |||
694 | #endif /* CONFIG_PM */ | ||
695 | |||
696 | |||
697 | static struct pci_driver ne2k_driver = { | ||
698 | .name = DRV_NAME, | ||
699 | .probe = ne2k_pci_init_one, | ||
700 | .remove = __devexit_p(ne2k_pci_remove_one), | ||
701 | .id_table = ne2k_pci_tbl, | ||
702 | #ifdef CONFIG_PM | ||
703 | .suspend = ne2k_pci_suspend, | ||
704 | .resume = ne2k_pci_resume, | ||
705 | #endif /* CONFIG_PM */ | ||
706 | |||
707 | }; | ||
708 | |||
709 | |||
710 | static int __init ne2k_pci_init(void) | ||
711 | { | ||
712 | /* when a module, this is printed whether or not devices are found in probe */ | ||
713 | #ifdef MODULE | ||
714 | printk(version); | ||
715 | #endif | ||
716 | return pci_register_driver(&ne2k_driver); | ||
717 | } | ||
718 | |||
719 | |||
720 | static void __exit ne2k_pci_cleanup(void) | ||
721 | { | ||
722 | pci_unregister_driver (&ne2k_driver); | ||
723 | } | ||
724 | |||
725 | module_init(ne2k_pci_init); | ||
726 | module_exit(ne2k_pci_cleanup); | ||
diff --git a/drivers/net/ethernet/8390/ne3210.c b/drivers/net/ethernet/8390/ne3210.c new file mode 100644 index 000000000000..243ed2aee88e --- /dev/null +++ b/drivers/net/ethernet/8390/ne3210.c | |||
@@ -0,0 +1,347 @@ | |||
1 | /* | ||
2 | ne3210.c | ||
3 | |||
4 | Linux driver for Novell NE3210 EISA Network Adapter | ||
5 | |||
6 | Copyright (C) 1998, Paul Gortmaker. | ||
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 | Information and Code Sources: | ||
12 | |||
13 | 1) Based upon my other EISA 8390 drivers (lne390, es3210, smc-ultra32) | ||
14 | 2) The existing myriad of other Linux 8390 drivers by Donald Becker. | ||
15 | 3) Info for getting IRQ and sh-mem gleaned from the EISA cfg file | ||
16 | |||
17 | The NE3210 is an EISA shared memory NS8390 implementation. Shared | ||
18 | memory address > 1MB should work with this driver. | ||
19 | |||
20 | Note that the .cfg file (3/11/93, v1.0) has AUI and BNC switched | ||
21 | around (or perhaps there are some defective/backwards cards ???) | ||
22 | |||
23 | This driver WILL NOT WORK FOR THE NE3200 - it is completely different | ||
24 | and does not use an 8390 at all. | ||
25 | |||
26 | Updated to EISA probing API 5/2003 by Marc Zyngier. | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/eisa.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/errno.h> | ||
33 | #include <linux/string.h> | ||
34 | #include <linux/delay.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/netdevice.h> | ||
38 | #include <linux/etherdevice.h> | ||
39 | #include <linux/mm.h> | ||
40 | |||
41 | #include <asm/io.h> | ||
42 | #include <asm/system.h> | ||
43 | |||
44 | #include "8390.h" | ||
45 | |||
46 | #define DRV_NAME "ne3210" | ||
47 | |||
48 | static void ne3210_reset_8390(struct net_device *dev); | ||
49 | |||
50 | static void ne3210_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page); | ||
51 | static void ne3210_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset); | ||
52 | static void ne3210_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page); | ||
53 | |||
54 | #define NE3210_START_PG 0x00 /* First page of TX buffer */ | ||
55 | #define NE3210_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
56 | |||
57 | #define NE3210_IO_EXTENT 0x20 | ||
58 | #define NE3210_SA_PROM 0x16 /* Start of e'net addr. */ | ||
59 | #define NE3210_RESET_PORT 0xc84 | ||
60 | #define NE3210_NIC_OFFSET 0x00 /* Hello, the 8390 is *here* */ | ||
61 | |||
62 | #define NE3210_ADDR0 0x00 /* 3 byte vendor prefix */ | ||
63 | #define NE3210_ADDR1 0x00 | ||
64 | #define NE3210_ADDR2 0x1b | ||
65 | |||
66 | #define NE3210_CFG1 0xc84 /* NB: 0xc84 is also "reset" port. */ | ||
67 | #define NE3210_CFG2 0xc90 | ||
68 | #define NE3210_CFG_EXTENT (NE3210_CFG2 - NE3210_CFG1 + 1) | ||
69 | |||
70 | /* | ||
71 | * You can OR any of the following bits together and assign it | ||
72 | * to NE3210_DEBUG to get verbose driver info during operation. | ||
73 | * Currently only the probe one is implemented. | ||
74 | */ | ||
75 | |||
76 | #define NE3210_D_PROBE 0x01 | ||
77 | #define NE3210_D_RX_PKT 0x02 | ||
78 | #define NE3210_D_TX_PKT 0x04 | ||
79 | #define NE3210_D_IRQ 0x08 | ||
80 | |||
81 | #define NE3210_DEBUG 0x0 | ||
82 | |||
83 | static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3}; | ||
84 | static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0}; | ||
85 | static const char *ifmap[] __initdata = {"UTP", "?", "BNC", "AUI"}; | ||
86 | static int ifmap_val[] __initdata = { | ||
87 | IF_PORT_10BASET, | ||
88 | IF_PORT_UNKNOWN, | ||
89 | IF_PORT_10BASE2, | ||
90 | IF_PORT_AUI, | ||
91 | }; | ||
92 | |||
93 | static int __init ne3210_eisa_probe (struct device *device) | ||
94 | { | ||
95 | unsigned long ioaddr, phys_mem; | ||
96 | int i, retval, port_index; | ||
97 | struct eisa_device *edev = to_eisa_device (device); | ||
98 | struct net_device *dev; | ||
99 | |||
100 | /* Allocate dev->priv and fill in 8390 specific dev fields. */ | ||
101 | if (!(dev = alloc_ei_netdev ())) { | ||
102 | printk ("ne3210.c: unable to allocate memory for dev!\n"); | ||
103 | return -ENOMEM; | ||
104 | } | ||
105 | |||
106 | SET_NETDEV_DEV(dev, device); | ||
107 | dev_set_drvdata(device, dev); | ||
108 | ioaddr = edev->base_addr; | ||
109 | |||
110 | if (!request_region(ioaddr, NE3210_IO_EXTENT, DRV_NAME)) { | ||
111 | retval = -EBUSY; | ||
112 | goto out; | ||
113 | } | ||
114 | |||
115 | if (!request_region(ioaddr + NE3210_CFG1, | ||
116 | NE3210_CFG_EXTENT, DRV_NAME)) { | ||
117 | retval = -EBUSY; | ||
118 | goto out1; | ||
119 | } | ||
120 | |||
121 | #if NE3210_DEBUG & NE3210_D_PROBE | ||
122 | printk("ne3210-debug: probe at %#x, ID %s\n", ioaddr, edev->id.sig); | ||
123 | printk("ne3210-debug: config regs: %#x %#x\n", | ||
124 | inb(ioaddr + NE3210_CFG1), inb(ioaddr + NE3210_CFG2)); | ||
125 | #endif | ||
126 | |||
127 | port_index = inb(ioaddr + NE3210_CFG2) >> 6; | ||
128 | for(i = 0; i < ETHER_ADDR_LEN; i++) | ||
129 | dev->dev_addr[i] = inb(ioaddr + NE3210_SA_PROM + i); | ||
130 | printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr: %pM.\n", | ||
131 | edev->slot, ifmap[port_index], dev->dev_addr); | ||
132 | |||
133 | /* Snarf the interrupt now. CFG file has them all listed as `edge' with share=NO */ | ||
134 | dev->irq = irq_map[(inb(ioaddr + NE3210_CFG2) >> 3) & 0x07]; | ||
135 | printk("ne3210.c: using IRQ %d, ", dev->irq); | ||
136 | |||
137 | retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev); | ||
138 | if (retval) { | ||
139 | printk (" unable to get IRQ %d.\n", dev->irq); | ||
140 | goto out2; | ||
141 | } | ||
142 | |||
143 | phys_mem = shmem_map[inb(ioaddr + NE3210_CFG2) & 0x07] * 0x1000; | ||
144 | |||
145 | /* | ||
146 | BEWARE!! Some dain-bramaged EISA SCUs will allow you to put | ||
147 | the card mem within the region covered by `normal' RAM !!! | ||
148 | */ | ||
149 | if (phys_mem > 1024*1024) { /* phys addr > 1MB */ | ||
150 | if (phys_mem < virt_to_phys(high_memory)) { | ||
151 | printk(KERN_CRIT "ne3210.c: Card RAM overlaps with normal memory!!!\n"); | ||
152 | printk(KERN_CRIT "ne3210.c: Use EISA SCU to set card memory below 1MB,\n"); | ||
153 | printk(KERN_CRIT "ne3210.c: or to an address above 0x%llx.\n", | ||
154 | (u64)virt_to_phys(high_memory)); | ||
155 | printk(KERN_CRIT "ne3210.c: Driver NOT installed.\n"); | ||
156 | retval = -EINVAL; | ||
157 | goto out3; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | if (!request_mem_region (phys_mem, NE3210_STOP_PG*0x100, DRV_NAME)) { | ||
162 | printk ("ne3210.c: Unable to request shared memory at physical address %#lx\n", | ||
163 | phys_mem); | ||
164 | goto out3; | ||
165 | } | ||
166 | |||
167 | printk("%dkB memory at physical address %#lx\n", | ||
168 | NE3210_STOP_PG/4, phys_mem); | ||
169 | |||
170 | ei_status.mem = ioremap(phys_mem, NE3210_STOP_PG*0x100); | ||
171 | if (!ei_status.mem) { | ||
172 | printk(KERN_ERR "ne3210.c: Unable to remap card memory !!\n"); | ||
173 | printk(KERN_ERR "ne3210.c: Driver NOT installed.\n"); | ||
174 | retval = -EAGAIN; | ||
175 | goto out4; | ||
176 | } | ||
177 | printk("ne3210.c: remapped %dkB card memory to virtual address %p\n", | ||
178 | NE3210_STOP_PG/4, ei_status.mem); | ||
179 | dev->mem_start = (unsigned long)ei_status.mem; | ||
180 | dev->mem_end = dev->mem_start + (NE3210_STOP_PG - NE3210_START_PG)*256; | ||
181 | |||
182 | /* The 8390 offset is zero for the NE3210 */ | ||
183 | dev->base_addr = ioaddr; | ||
184 | |||
185 | ei_status.name = "NE3210"; | ||
186 | ei_status.tx_start_page = NE3210_START_PG; | ||
187 | ei_status.rx_start_page = NE3210_START_PG + TX_PAGES; | ||
188 | ei_status.stop_page = NE3210_STOP_PG; | ||
189 | ei_status.word16 = 1; | ||
190 | ei_status.priv = phys_mem; | ||
191 | |||
192 | if (ei_debug > 0) | ||
193 | printk("ne3210 loaded.\n"); | ||
194 | |||
195 | ei_status.reset_8390 = &ne3210_reset_8390; | ||
196 | ei_status.block_input = &ne3210_block_input; | ||
197 | ei_status.block_output = &ne3210_block_output; | ||
198 | ei_status.get_8390_hdr = &ne3210_get_8390_hdr; | ||
199 | |||
200 | dev->netdev_ops = &ei_netdev_ops; | ||
201 | |||
202 | dev->if_port = ifmap_val[port_index]; | ||
203 | |||
204 | if ((retval = register_netdev (dev))) | ||
205 | goto out5; | ||
206 | |||
207 | NS8390_init(dev, 0); | ||
208 | return 0; | ||
209 | |||
210 | out5: | ||
211 | iounmap(ei_status.mem); | ||
212 | out4: | ||
213 | release_mem_region (phys_mem, NE3210_STOP_PG*0x100); | ||
214 | out3: | ||
215 | free_irq (dev->irq, dev); | ||
216 | out2: | ||
217 | release_region (ioaddr + NE3210_CFG1, NE3210_CFG_EXTENT); | ||
218 | out1: | ||
219 | release_region (ioaddr, NE3210_IO_EXTENT); | ||
220 | out: | ||
221 | free_netdev (dev); | ||
222 | |||
223 | return retval; | ||
224 | } | ||
225 | |||
226 | static int __devexit ne3210_eisa_remove (struct device *device) | ||
227 | { | ||
228 | struct net_device *dev = dev_get_drvdata(device); | ||
229 | unsigned long ioaddr = to_eisa_device (device)->base_addr; | ||
230 | |||
231 | unregister_netdev (dev); | ||
232 | iounmap(ei_status.mem); | ||
233 | release_mem_region (ei_status.priv, NE3210_STOP_PG*0x100); | ||
234 | free_irq (dev->irq, dev); | ||
235 | release_region (ioaddr + NE3210_CFG1, NE3210_CFG_EXTENT); | ||
236 | release_region (ioaddr, NE3210_IO_EXTENT); | ||
237 | free_netdev (dev); | ||
238 | |||
239 | return 0; | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * Reset by toggling the "Board Enable" bits (bit 2 and 0). | ||
244 | */ | ||
245 | |||
246 | static void ne3210_reset_8390(struct net_device *dev) | ||
247 | { | ||
248 | unsigned short ioaddr = dev->base_addr; | ||
249 | |||
250 | outb(0x04, ioaddr + NE3210_RESET_PORT); | ||
251 | if (ei_debug > 1) printk("%s: resetting the NE3210...", dev->name); | ||
252 | |||
253 | mdelay(2); | ||
254 | |||
255 | ei_status.txing = 0; | ||
256 | outb(0x01, ioaddr + NE3210_RESET_PORT); | ||
257 | if (ei_debug > 1) printk("reset done\n"); | ||
258 | } | ||
259 | |||
260 | /* | ||
261 | * Note: In the following three functions is the implicit assumption | ||
262 | * that the associated memcpy will only use "rep; movsl" as long as | ||
263 | * we keep the counts as some multiple of doublewords. This is a | ||
264 | * requirement of the hardware, and also prevents us from using | ||
265 | * eth_io_copy_and_sum() since we can't guarantee it will limit | ||
266 | * itself to doubleword access. | ||
267 | */ | ||
268 | |||
269 | /* | ||
270 | * Grab the 8390 specific header. Similar to the block_input routine, but | ||
271 | * we don't need to be concerned with ring wrap as the header will be at | ||
272 | * the start of a page, so we optimize accordingly. (A single doubleword.) | ||
273 | */ | ||
274 | |||
275 | static void | ||
276 | ne3210_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
277 | { | ||
278 | void __iomem *hdr_start = ei_status.mem + ((ring_page - NE3210_START_PG)<<8); | ||
279 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
280 | hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */ | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * Block input and output are easy on shared memory ethercards, the only | ||
285 | * complication is when the ring buffer wraps. The count will already | ||
286 | * be rounded up to a doubleword value via ne3210_get_8390_hdr() above. | ||
287 | */ | ||
288 | |||
289 | static void ne3210_block_input(struct net_device *dev, int count, struct sk_buff *skb, | ||
290 | int ring_offset) | ||
291 | { | ||
292 | void __iomem *start = ei_status.mem + ring_offset - NE3210_START_PG*256; | ||
293 | |||
294 | if (ring_offset + count > NE3210_STOP_PG*256) { | ||
295 | /* Packet wraps over end of ring buffer. */ | ||
296 | int semi_count = NE3210_STOP_PG*256 - ring_offset; | ||
297 | memcpy_fromio(skb->data, start, semi_count); | ||
298 | count -= semi_count; | ||
299 | memcpy_fromio(skb->data + semi_count, | ||
300 | ei_status.mem + TX_PAGES*256, count); | ||
301 | } else { | ||
302 | /* Packet is in one chunk. */ | ||
303 | memcpy_fromio(skb->data, start, count); | ||
304 | } | ||
305 | } | ||
306 | |||
307 | static void ne3210_block_output(struct net_device *dev, int count, | ||
308 | const unsigned char *buf, int start_page) | ||
309 | { | ||
310 | void __iomem *shmem = ei_status.mem + ((start_page - NE3210_START_PG)<<8); | ||
311 | |||
312 | count = (count + 3) & ~3; /* Round up to doubleword */ | ||
313 | memcpy_toio(shmem, buf, count); | ||
314 | } | ||
315 | |||
316 | static struct eisa_device_id ne3210_ids[] = { | ||
317 | { "EGL0101" }, | ||
318 | { "NVL1801" }, | ||
319 | { "" }, | ||
320 | }; | ||
321 | MODULE_DEVICE_TABLE(eisa, ne3210_ids); | ||
322 | |||
323 | static struct eisa_driver ne3210_eisa_driver = { | ||
324 | .id_table = ne3210_ids, | ||
325 | .driver = { | ||
326 | .name = "ne3210", | ||
327 | .probe = ne3210_eisa_probe, | ||
328 | .remove = __devexit_p (ne3210_eisa_remove), | ||
329 | }, | ||
330 | }; | ||
331 | |||
332 | MODULE_DESCRIPTION("NE3210 EISA Ethernet driver"); | ||
333 | MODULE_LICENSE("GPL"); | ||
334 | MODULE_DEVICE_TABLE(eisa, ne3210_ids); | ||
335 | |||
336 | static int ne3210_init(void) | ||
337 | { | ||
338 | return eisa_driver_register (&ne3210_eisa_driver); | ||
339 | } | ||
340 | |||
341 | static void ne3210_cleanup(void) | ||
342 | { | ||
343 | eisa_driver_unregister (&ne3210_eisa_driver); | ||
344 | } | ||
345 | |||
346 | module_init (ne3210_init); | ||
347 | module_exit (ne3210_cleanup); | ||
diff --git a/drivers/net/ethernet/8390/pcnet_cs.c b/drivers/net/ethernet/8390/pcnet_cs.c new file mode 100644 index 000000000000..40107614b5dc --- /dev/null +++ b/drivers/net/ethernet/8390/pcnet_cs.c | |||
@@ -0,0 +1,1710 @@ | |||
1 | /*====================================================================== | ||
2 | |||
3 | A PCMCIA ethernet driver for NS8390-based cards | ||
4 | |||
5 | This driver supports the D-Link DE-650 and Linksys EthernetCard | ||
6 | cards, the newer D-Link and Linksys combo cards, Accton EN2212 | ||
7 | cards, the RPTI EP400, and the PreMax PE-200 in non-shared-memory | ||
8 | mode, and the IBM Credit Card Adapter, the NE4100, the Thomas | ||
9 | Conrad ethernet card, and the Kingston KNE-PCM/x in shared-memory | ||
10 | mode. It will also handle the Socket EA card in either mode. | ||
11 | |||
12 | Copyright (C) 1999 David A. Hinds -- dahinds@users.sourceforge.net | ||
13 | |||
14 | pcnet_cs.c 1.153 2003/11/09 18:53:09 | ||
15 | |||
16 | The network driver code is based on Donald Becker's NE2000 code: | ||
17 | |||
18 | Written 1992,1993 by Donald Becker. | ||
19 | Copyright 1993 United States Government as represented by the | ||
20 | Director, National Security Agency. This software may be used and | ||
21 | distributed according to the terms of the GNU General Public License, | ||
22 | incorporated herein by reference. | ||
23 | Donald Becker may be reached at becker@scyld.com | ||
24 | |||
25 | Based also on Keith Moore's changes to Don Becker's code, for IBM | ||
26 | CCAE support. Drivers merged back together, and shared-memory | ||
27 | Socket EA support added, by Ken Raeburn, September 1995. | ||
28 | |||
29 | ======================================================================*/ | ||
30 | |||
31 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
32 | |||
33 | #include <linux/kernel.h> | ||
34 | #include <linux/module.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/ptrace.h> | ||
37 | #include <linux/string.h> | ||
38 | #include <linux/timer.h> | ||
39 | #include <linux/delay.h> | ||
40 | #include <linux/netdevice.h> | ||
41 | #include <linux/log2.h> | ||
42 | #include <linux/etherdevice.h> | ||
43 | #include <linux/mii.h> | ||
44 | #include "8390.h" | ||
45 | |||
46 | #include <pcmcia/cistpl.h> | ||
47 | #include <pcmcia/ciscode.h> | ||
48 | #include <pcmcia/ds.h> | ||
49 | #include <pcmcia/cisreg.h> | ||
50 | |||
51 | #include <asm/io.h> | ||
52 | #include <asm/system.h> | ||
53 | #include <asm/byteorder.h> | ||
54 | #include <asm/uaccess.h> | ||
55 | |||
56 | #define PCNET_CMD 0x00 | ||
57 | #define PCNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */ | ||
58 | #define PCNET_RESET 0x1f /* Issue a read to reset, a write to clear. */ | ||
59 | #define PCNET_MISC 0x18 /* For IBM CCAE and Socket EA cards */ | ||
60 | |||
61 | #define PCNET_START_PG 0x40 /* First page of TX buffer */ | ||
62 | #define PCNET_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
63 | |||
64 | /* Socket EA cards have a larger packet buffer */ | ||
65 | #define SOCKET_START_PG 0x01 | ||
66 | #define SOCKET_STOP_PG 0xff | ||
67 | |||
68 | #define PCNET_RDC_TIMEOUT (2*HZ/100) /* Max wait in jiffies for Tx RDC */ | ||
69 | |||
70 | static const char *if_names[] = { "auto", "10baseT", "10base2"}; | ||
71 | |||
72 | |||
73 | /*====================================================================*/ | ||
74 | |||
75 | /* Module parameters */ | ||
76 | |||
77 | MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>"); | ||
78 | MODULE_DESCRIPTION("NE2000 compatible PCMCIA ethernet driver"); | ||
79 | MODULE_LICENSE("GPL"); | ||
80 | |||
81 | #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0) | ||
82 | |||
83 | INT_MODULE_PARM(if_port, 1); /* Transceiver type */ | ||
84 | INT_MODULE_PARM(use_big_buf, 1); /* use 64K packet buffer? */ | ||
85 | INT_MODULE_PARM(mem_speed, 0); /* shared mem speed, in ns */ | ||
86 | INT_MODULE_PARM(delay_output, 0); /* pause after xmit? */ | ||
87 | INT_MODULE_PARM(delay_time, 4); /* in usec */ | ||
88 | INT_MODULE_PARM(use_shmem, -1); /* use shared memory? */ | ||
89 | INT_MODULE_PARM(full_duplex, 0); /* full duplex? */ | ||
90 | |||
91 | /* Ugh! Let the user hardwire the hardware address for queer cards */ | ||
92 | static int hw_addr[6] = { 0, /* ... */ }; | ||
93 | module_param_array(hw_addr, int, NULL, 0); | ||
94 | |||
95 | /*====================================================================*/ | ||
96 | |||
97 | static void mii_phy_probe(struct net_device *dev); | ||
98 | static int pcnet_config(struct pcmcia_device *link); | ||
99 | static void pcnet_release(struct pcmcia_device *link); | ||
100 | static int pcnet_open(struct net_device *dev); | ||
101 | static int pcnet_close(struct net_device *dev); | ||
102 | static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | ||
103 | static irqreturn_t ei_irq_wrapper(int irq, void *dev_id); | ||
104 | static void ei_watchdog(u_long arg); | ||
105 | static void pcnet_reset_8390(struct net_device *dev); | ||
106 | static int set_config(struct net_device *dev, struct ifmap *map); | ||
107 | static int setup_shmem_window(struct pcmcia_device *link, int start_pg, | ||
108 | int stop_pg, int cm_offset); | ||
109 | static int setup_dma_config(struct pcmcia_device *link, int start_pg, | ||
110 | int stop_pg); | ||
111 | |||
112 | static void pcnet_detach(struct pcmcia_device *p_dev); | ||
113 | |||
114 | /*====================================================================*/ | ||
115 | |||
116 | typedef struct hw_info_t { | ||
117 | u_int offset; | ||
118 | u_char a0, a1, a2; | ||
119 | u_int flags; | ||
120 | } hw_info_t; | ||
121 | |||
122 | #define DELAY_OUTPUT 0x01 | ||
123 | #define HAS_MISC_REG 0x02 | ||
124 | #define USE_BIG_BUF 0x04 | ||
125 | #define HAS_IBM_MISC 0x08 | ||
126 | #define IS_DL10019 0x10 | ||
127 | #define IS_DL10022 0x20 | ||
128 | #define HAS_MII 0x40 | ||
129 | #define USE_SHMEM 0x80 /* autodetected */ | ||
130 | |||
131 | #define AM79C9XX_HOME_PHY 0x00006B90 /* HomePNA PHY */ | ||
132 | #define AM79C9XX_ETH_PHY 0x00006B70 /* 10baseT PHY */ | ||
133 | #define MII_PHYID_REV_MASK 0xfffffff0 | ||
134 | #define MII_PHYID_REG1 0x02 | ||
135 | #define MII_PHYID_REG2 0x03 | ||
136 | |||
137 | static hw_info_t hw_info[] = { | ||
138 | { /* Accton EN2212 */ 0x0ff0, 0x00, 0x00, 0xe8, DELAY_OUTPUT }, | ||
139 | { /* Allied Telesis LA-PCM */ 0x0ff0, 0x00, 0x00, 0xf4, 0 }, | ||
140 | { /* APEX MultiCard */ 0x03f4, 0x00, 0x20, 0xe5, 0 }, | ||
141 | { /* ASANTE FriendlyNet */ 0x4910, 0x00, 0x00, 0x94, | ||
142 | DELAY_OUTPUT | HAS_IBM_MISC }, | ||
143 | { /* Danpex EN-6200P2 */ 0x0110, 0x00, 0x40, 0xc7, 0 }, | ||
144 | { /* DataTrek NetCard */ 0x0ff0, 0x00, 0x20, 0xe8, 0 }, | ||
145 | { /* Dayna CommuniCard E */ 0x0110, 0x00, 0x80, 0x19, 0 }, | ||
146 | { /* D-Link DE-650 */ 0x0040, 0x00, 0x80, 0xc8, 0 }, | ||
147 | { /* EP-210 Ethernet */ 0x0110, 0x00, 0x40, 0x33, 0 }, | ||
148 | { /* EP4000 Ethernet */ 0x01c0, 0x00, 0x00, 0xb4, 0 }, | ||
149 | { /* Epson EEN10B */ 0x0ff0, 0x00, 0x00, 0x48, | ||
150 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
151 | { /* ELECOM Laneed LD-CDWA */ 0xb8, 0x08, 0x00, 0x42, 0 }, | ||
152 | { /* Hypertec Ethernet */ 0x01c0, 0x00, 0x40, 0x4c, 0 }, | ||
153 | { /* IBM CCAE */ 0x0ff0, 0x08, 0x00, 0x5a, | ||
154 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
155 | { /* IBM CCAE */ 0x0ff0, 0x00, 0x04, 0xac, | ||
156 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
157 | { /* IBM CCAE */ 0x0ff0, 0x00, 0x06, 0x29, | ||
158 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
159 | { /* IBM FME */ 0x0374, 0x08, 0x00, 0x5a, | ||
160 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
161 | { /* IBM FME */ 0x0374, 0x00, 0x04, 0xac, | ||
162 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
163 | { /* Kansai KLA-PCM/T */ 0x0ff0, 0x00, 0x60, 0x87, | ||
164 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
165 | { /* NSC DP83903 */ 0x0374, 0x08, 0x00, 0x17, | ||
166 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
167 | { /* NSC DP83903 */ 0x0374, 0x00, 0xc0, 0xa8, | ||
168 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
169 | { /* NSC DP83903 */ 0x0374, 0x00, 0xa0, 0xb0, | ||
170 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
171 | { /* NSC DP83903 */ 0x0198, 0x00, 0x20, 0xe0, | ||
172 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
173 | { /* I-O DATA PCLA/T */ 0x0ff0, 0x00, 0xa0, 0xb0, 0 }, | ||
174 | { /* Katron PE-520 */ 0x0110, 0x00, 0x40, 0xf6, 0 }, | ||
175 | { /* Kingston KNE-PCM/x */ 0x0ff0, 0x00, 0xc0, 0xf0, | ||
176 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
177 | { /* Kingston KNE-PCM/x */ 0x0ff0, 0xe2, 0x0c, 0x0f, | ||
178 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
179 | { /* Kingston KNE-PC2 */ 0x0180, 0x00, 0xc0, 0xf0, 0 }, | ||
180 | { /* Maxtech PCN2000 */ 0x5000, 0x00, 0x00, 0xe8, 0 }, | ||
181 | { /* NDC Instant-Link */ 0x003a, 0x00, 0x80, 0xc6, 0 }, | ||
182 | { /* NE2000 Compatible */ 0x0ff0, 0x00, 0xa0, 0x0c, 0 }, | ||
183 | { /* Network General Sniffer */ 0x0ff0, 0x00, 0x00, 0x65, | ||
184 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
185 | { /* Panasonic VEL211 */ 0x0ff0, 0x00, 0x80, 0x45, | ||
186 | HAS_MISC_REG | HAS_IBM_MISC }, | ||
187 | { /* PreMax PE-200 */ 0x07f0, 0x00, 0x20, 0xe0, 0 }, | ||
188 | { /* RPTI EP400 */ 0x0110, 0x00, 0x40, 0x95, 0 }, | ||
189 | { /* SCM Ethernet */ 0x0ff0, 0x00, 0x20, 0xcb, 0 }, | ||
190 | { /* Socket EA */ 0x4000, 0x00, 0xc0, 0x1b, | ||
191 | DELAY_OUTPUT | HAS_MISC_REG | USE_BIG_BUF }, | ||
192 | { /* Socket LP-E CF+ */ 0x01c0, 0x00, 0xc0, 0x1b, 0 }, | ||
193 | { /* SuperSocket RE450T */ 0x0110, 0x00, 0xe0, 0x98, 0 }, | ||
194 | { /* Volktek NPL-402CT */ 0x0060, 0x00, 0x40, 0x05, 0 }, | ||
195 | { /* NEC PC-9801N-J12 */ 0x0ff0, 0x00, 0x00, 0x4c, 0 }, | ||
196 | { /* PCMCIA Technology OEM */ 0x01c8, 0x00, 0xa0, 0x0c, 0 } | ||
197 | }; | ||
198 | |||
199 | #define NR_INFO ARRAY_SIZE(hw_info) | ||
200 | |||
201 | static hw_info_t default_info = { 0, 0, 0, 0, 0 }; | ||
202 | static hw_info_t dl10019_info = { 0, 0, 0, 0, IS_DL10019|HAS_MII }; | ||
203 | static hw_info_t dl10022_info = { 0, 0, 0, 0, IS_DL10022|HAS_MII }; | ||
204 | |||
205 | typedef struct pcnet_dev_t { | ||
206 | struct pcmcia_device *p_dev; | ||
207 | u_int flags; | ||
208 | void __iomem *base; | ||
209 | struct timer_list watchdog; | ||
210 | int stale, fast_poll; | ||
211 | u_char phy_id; | ||
212 | u_char eth_phy, pna_phy; | ||
213 | u_short link_status; | ||
214 | u_long mii_reset; | ||
215 | } pcnet_dev_t; | ||
216 | |||
217 | static inline pcnet_dev_t *PRIV(struct net_device *dev) | ||
218 | { | ||
219 | char *p = netdev_priv(dev); | ||
220 | return (pcnet_dev_t *)(p + sizeof(struct ei_device)); | ||
221 | } | ||
222 | |||
223 | static const struct net_device_ops pcnet_netdev_ops = { | ||
224 | .ndo_open = pcnet_open, | ||
225 | .ndo_stop = pcnet_close, | ||
226 | .ndo_set_config = set_config, | ||
227 | .ndo_start_xmit = ei_start_xmit, | ||
228 | .ndo_get_stats = ei_get_stats, | ||
229 | .ndo_do_ioctl = ei_ioctl, | ||
230 | .ndo_set_multicast_list = ei_set_multicast_list, | ||
231 | .ndo_tx_timeout = ei_tx_timeout, | ||
232 | .ndo_change_mtu = eth_change_mtu, | ||
233 | .ndo_set_mac_address = eth_mac_addr, | ||
234 | .ndo_validate_addr = eth_validate_addr, | ||
235 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
236 | .ndo_poll_controller = ei_poll, | ||
237 | #endif | ||
238 | }; | ||
239 | |||
240 | static int pcnet_probe(struct pcmcia_device *link) | ||
241 | { | ||
242 | pcnet_dev_t *info; | ||
243 | struct net_device *dev; | ||
244 | |||
245 | dev_dbg(&link->dev, "pcnet_attach()\n"); | ||
246 | |||
247 | /* Create new ethernet device */ | ||
248 | dev = __alloc_ei_netdev(sizeof(pcnet_dev_t)); | ||
249 | if (!dev) return -ENOMEM; | ||
250 | info = PRIV(dev); | ||
251 | info->p_dev = link; | ||
252 | link->priv = dev; | ||
253 | |||
254 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; | ||
255 | |||
256 | dev->netdev_ops = &pcnet_netdev_ops; | ||
257 | |||
258 | return pcnet_config(link); | ||
259 | } /* pcnet_attach */ | ||
260 | |||
261 | static void pcnet_detach(struct pcmcia_device *link) | ||
262 | { | ||
263 | struct net_device *dev = link->priv; | ||
264 | |||
265 | dev_dbg(&link->dev, "pcnet_detach\n"); | ||
266 | |||
267 | unregister_netdev(dev); | ||
268 | |||
269 | pcnet_release(link); | ||
270 | |||
271 | free_netdev(dev); | ||
272 | } /* pcnet_detach */ | ||
273 | |||
274 | /*====================================================================== | ||
275 | |||
276 | This probes for a card's hardware address, for card types that | ||
277 | encode this information in their CIS. | ||
278 | |||
279 | ======================================================================*/ | ||
280 | |||
281 | static hw_info_t *get_hwinfo(struct pcmcia_device *link) | ||
282 | { | ||
283 | struct net_device *dev = link->priv; | ||
284 | u_char __iomem *base, *virt; | ||
285 | int i, j; | ||
286 | |||
287 | /* Allocate a small memory window */ | ||
288 | link->resource[2]->flags |= WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE; | ||
289 | link->resource[2]->start = 0; link->resource[2]->end = 0; | ||
290 | i = pcmcia_request_window(link, link->resource[2], 0); | ||
291 | if (i != 0) | ||
292 | return NULL; | ||
293 | |||
294 | virt = ioremap(link->resource[2]->start, | ||
295 | resource_size(link->resource[2])); | ||
296 | for (i = 0; i < NR_INFO; i++) { | ||
297 | pcmcia_map_mem_page(link, link->resource[2], | ||
298 | hw_info[i].offset & ~(resource_size(link->resource[2])-1)); | ||
299 | base = &virt[hw_info[i].offset & (resource_size(link->resource[2])-1)]; | ||
300 | if ((readb(base+0) == hw_info[i].a0) && | ||
301 | (readb(base+2) == hw_info[i].a1) && | ||
302 | (readb(base+4) == hw_info[i].a2)) { | ||
303 | for (j = 0; j < 6; j++) | ||
304 | dev->dev_addr[j] = readb(base + (j<<1)); | ||
305 | break; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | iounmap(virt); | ||
310 | j = pcmcia_release_window(link, link->resource[2]); | ||
311 | return (i < NR_INFO) ? hw_info+i : NULL; | ||
312 | } /* get_hwinfo */ | ||
313 | |||
314 | /*====================================================================== | ||
315 | |||
316 | This probes for a card's hardware address by reading the PROM. | ||
317 | It checks the address against a list of known types, then falls | ||
318 | back to a simple NE2000 clone signature check. | ||
319 | |||
320 | ======================================================================*/ | ||
321 | |||
322 | static hw_info_t *get_prom(struct pcmcia_device *link) | ||
323 | { | ||
324 | struct net_device *dev = link->priv; | ||
325 | unsigned int ioaddr = dev->base_addr; | ||
326 | u_char prom[32]; | ||
327 | int i, j; | ||
328 | |||
329 | /* This is lifted straight from drivers/net/ne.c */ | ||
330 | struct { | ||
331 | u_char value, offset; | ||
332 | } program_seq[] = { | ||
333 | {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/ | ||
334 | {0x48, EN0_DCFG}, /* Set byte-wide (0x48) access. */ | ||
335 | {0x00, EN0_RCNTLO}, /* Clear the count regs. */ | ||
336 | {0x00, EN0_RCNTHI}, | ||
337 | {0x00, EN0_IMR}, /* Mask completion irq. */ | ||
338 | {0xFF, EN0_ISR}, | ||
339 | {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */ | ||
340 | {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */ | ||
341 | {32, EN0_RCNTLO}, | ||
342 | {0x00, EN0_RCNTHI}, | ||
343 | {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */ | ||
344 | {0x00, EN0_RSARHI}, | ||
345 | {E8390_RREAD+E8390_START, E8390_CMD}, | ||
346 | }; | ||
347 | |||
348 | pcnet_reset_8390(dev); | ||
349 | mdelay(10); | ||
350 | |||
351 | for (i = 0; i < ARRAY_SIZE(program_seq); i++) | ||
352 | outb_p(program_seq[i].value, ioaddr + program_seq[i].offset); | ||
353 | |||
354 | for (i = 0; i < 32; i++) | ||
355 | prom[i] = inb(ioaddr + PCNET_DATAPORT); | ||
356 | for (i = 0; i < NR_INFO; i++) { | ||
357 | if ((prom[0] == hw_info[i].a0) && | ||
358 | (prom[2] == hw_info[i].a1) && | ||
359 | (prom[4] == hw_info[i].a2)) | ||
360 | break; | ||
361 | } | ||
362 | if ((i < NR_INFO) || ((prom[28] == 0x57) && (prom[30] == 0x57))) { | ||
363 | for (j = 0; j < 6; j++) | ||
364 | dev->dev_addr[j] = prom[j<<1]; | ||
365 | return (i < NR_INFO) ? hw_info+i : &default_info; | ||
366 | } | ||
367 | return NULL; | ||
368 | } /* get_prom */ | ||
369 | |||
370 | /*====================================================================== | ||
371 | |||
372 | For DL10019 based cards, like the Linksys EtherFast | ||
373 | |||
374 | ======================================================================*/ | ||
375 | |||
376 | static hw_info_t *get_dl10019(struct pcmcia_device *link) | ||
377 | { | ||
378 | struct net_device *dev = link->priv; | ||
379 | int i; | ||
380 | u_char sum; | ||
381 | |||
382 | for (sum = 0, i = 0x14; i < 0x1c; i++) | ||
383 | sum += inb_p(dev->base_addr + i); | ||
384 | if (sum != 0xff) | ||
385 | return NULL; | ||
386 | for (i = 0; i < 6; i++) | ||
387 | dev->dev_addr[i] = inb_p(dev->base_addr + 0x14 + i); | ||
388 | i = inb(dev->base_addr + 0x1f); | ||
389 | return ((i == 0x91)||(i == 0x99)) ? &dl10022_info : &dl10019_info; | ||
390 | } | ||
391 | |||
392 | /*====================================================================== | ||
393 | |||
394 | For Asix AX88190 based cards | ||
395 | |||
396 | ======================================================================*/ | ||
397 | |||
398 | static hw_info_t *get_ax88190(struct pcmcia_device *link) | ||
399 | { | ||
400 | struct net_device *dev = link->priv; | ||
401 | unsigned int ioaddr = dev->base_addr; | ||
402 | int i, j; | ||
403 | |||
404 | /* Not much of a test, but the alternatives are messy */ | ||
405 | if (link->config_base != 0x03c0) | ||
406 | return NULL; | ||
407 | |||
408 | outb_p(0x01, ioaddr + EN0_DCFG); /* Set word-wide access. */ | ||
409 | outb_p(0x00, ioaddr + EN0_RSARLO); /* DMA starting at 0x0400. */ | ||
410 | outb_p(0x04, ioaddr + EN0_RSARHI); | ||
411 | outb_p(E8390_RREAD+E8390_START, ioaddr + E8390_CMD); | ||
412 | |||
413 | for (i = 0; i < 6; i += 2) { | ||
414 | j = inw(ioaddr + PCNET_DATAPORT); | ||
415 | dev->dev_addr[i] = j & 0xff; | ||
416 | dev->dev_addr[i+1] = j >> 8; | ||
417 | } | ||
418 | return NULL; | ||
419 | } | ||
420 | |||
421 | /*====================================================================== | ||
422 | |||
423 | This should be totally unnecessary... but when we can't figure | ||
424 | out the hardware address any other way, we'll let the user hard | ||
425 | wire it when the module is initialized. | ||
426 | |||
427 | ======================================================================*/ | ||
428 | |||
429 | static hw_info_t *get_hwired(struct pcmcia_device *link) | ||
430 | { | ||
431 | struct net_device *dev = link->priv; | ||
432 | int i; | ||
433 | |||
434 | for (i = 0; i < 6; i++) | ||
435 | if (hw_addr[i] != 0) break; | ||
436 | if (i == 6) | ||
437 | return NULL; | ||
438 | |||
439 | for (i = 0; i < 6; i++) | ||
440 | dev->dev_addr[i] = hw_addr[i]; | ||
441 | |||
442 | return &default_info; | ||
443 | } /* get_hwired */ | ||
444 | |||
445 | static int try_io_port(struct pcmcia_device *link) | ||
446 | { | ||
447 | int j, ret; | ||
448 | link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; | ||
449 | link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH; | ||
450 | if (link->resource[0]->end == 32) { | ||
451 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; | ||
452 | if (link->resource[1]->end > 0) { | ||
453 | /* for master/slave multifunction cards */ | ||
454 | link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8; | ||
455 | } | ||
456 | } else { | ||
457 | /* This should be two 16-port windows */ | ||
458 | link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8; | ||
459 | link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16; | ||
460 | } | ||
461 | if (link->resource[0]->start == 0) { | ||
462 | for (j = 0; j < 0x400; j += 0x20) { | ||
463 | link->resource[0]->start = j ^ 0x300; | ||
464 | link->resource[1]->start = (j ^ 0x300) + 0x10; | ||
465 | link->io_lines = 16; | ||
466 | ret = pcmcia_request_io(link); | ||
467 | if (ret == 0) | ||
468 | return ret; | ||
469 | } | ||
470 | return ret; | ||
471 | } else { | ||
472 | return pcmcia_request_io(link); | ||
473 | } | ||
474 | } | ||
475 | |||
476 | static int pcnet_confcheck(struct pcmcia_device *p_dev, void *priv_data) | ||
477 | { | ||
478 | int *priv = priv_data; | ||
479 | int try = (*priv & 0x1); | ||
480 | |||
481 | *priv &= (p_dev->resource[2]->end >= 0x4000) ? 0x10 : ~0x10; | ||
482 | |||
483 | if (p_dev->config_index == 0) | ||
484 | return -EINVAL; | ||
485 | |||
486 | if (p_dev->resource[0]->end + p_dev->resource[1]->end < 32) | ||
487 | return -EINVAL; | ||
488 | |||
489 | if (try) | ||
490 | p_dev->io_lines = 16; | ||
491 | return try_io_port(p_dev); | ||
492 | } | ||
493 | |||
494 | static hw_info_t *pcnet_try_config(struct pcmcia_device *link, | ||
495 | int *has_shmem, int try) | ||
496 | { | ||
497 | struct net_device *dev = link->priv; | ||
498 | hw_info_t *local_hw_info; | ||
499 | pcnet_dev_t *info = PRIV(dev); | ||
500 | int priv = try; | ||
501 | int ret; | ||
502 | |||
503 | ret = pcmcia_loop_config(link, pcnet_confcheck, &priv); | ||
504 | if (ret) { | ||
505 | dev_warn(&link->dev, "no useable port range found\n"); | ||
506 | return NULL; | ||
507 | } | ||
508 | *has_shmem = (priv & 0x10); | ||
509 | |||
510 | if (!link->irq) | ||
511 | return NULL; | ||
512 | |||
513 | if (resource_size(link->resource[1]) == 8) | ||
514 | link->config_flags |= CONF_ENABLE_SPKR; | ||
515 | |||
516 | if ((link->manf_id == MANFID_IBM) && | ||
517 | (link->card_id == PRODID_IBM_HOME_AND_AWAY)) | ||
518 | link->config_index |= 0x10; | ||
519 | |||
520 | ret = pcmcia_enable_device(link); | ||
521 | if (ret) | ||
522 | return NULL; | ||
523 | |||
524 | dev->irq = link->irq; | ||
525 | dev->base_addr = link->resource[0]->start; | ||
526 | |||
527 | if (info->flags & HAS_MISC_REG) { | ||
528 | if ((if_port == 1) || (if_port == 2)) | ||
529 | dev->if_port = if_port; | ||
530 | else | ||
531 | dev_notice(&link->dev, "invalid if_port requested\n"); | ||
532 | } else | ||
533 | dev->if_port = 0; | ||
534 | |||
535 | if ((link->config_base == 0x03c0) && | ||
536 | (link->manf_id == 0x149) && (link->card_id == 0xc1ab)) { | ||
537 | dev_info(&link->dev, | ||
538 | "this is an AX88190 card - use axnet_cs instead.\n"); | ||
539 | return NULL; | ||
540 | } | ||
541 | |||
542 | local_hw_info = get_hwinfo(link); | ||
543 | if (!local_hw_info) | ||
544 | local_hw_info = get_prom(link); | ||
545 | if (!local_hw_info) | ||
546 | local_hw_info = get_dl10019(link); | ||
547 | if (!local_hw_info) | ||
548 | local_hw_info = get_ax88190(link); | ||
549 | if (!local_hw_info) | ||
550 | local_hw_info = get_hwired(link); | ||
551 | |||
552 | return local_hw_info; | ||
553 | } | ||
554 | |||
555 | static int pcnet_config(struct pcmcia_device *link) | ||
556 | { | ||
557 | struct net_device *dev = link->priv; | ||
558 | pcnet_dev_t *info = PRIV(dev); | ||
559 | int start_pg, stop_pg, cm_offset; | ||
560 | int has_shmem = 0; | ||
561 | hw_info_t *local_hw_info; | ||
562 | |||
563 | dev_dbg(&link->dev, "pcnet_config\n"); | ||
564 | |||
565 | local_hw_info = pcnet_try_config(link, &has_shmem, 0); | ||
566 | if (!local_hw_info) { | ||
567 | /* check whether forcing io_lines to 16 helps... */ | ||
568 | pcmcia_disable_device(link); | ||
569 | local_hw_info = pcnet_try_config(link, &has_shmem, 1); | ||
570 | if (local_hw_info == NULL) { | ||
571 | dev_notice(&link->dev, "unable to read hardware net" | ||
572 | " address for io base %#3lx\n", dev->base_addr); | ||
573 | goto failed; | ||
574 | } | ||
575 | } | ||
576 | |||
577 | info->flags = local_hw_info->flags; | ||
578 | /* Check for user overrides */ | ||
579 | info->flags |= (delay_output) ? DELAY_OUTPUT : 0; | ||
580 | if ((link->manf_id == MANFID_SOCKET) && | ||
581 | ((link->card_id == PRODID_SOCKET_LPE) || | ||
582 | (link->card_id == PRODID_SOCKET_LPE_CF) || | ||
583 | (link->card_id == PRODID_SOCKET_EIO))) | ||
584 | info->flags &= ~USE_BIG_BUF; | ||
585 | if (!use_big_buf) | ||
586 | info->flags &= ~USE_BIG_BUF; | ||
587 | |||
588 | if (info->flags & USE_BIG_BUF) { | ||
589 | start_pg = SOCKET_START_PG; | ||
590 | stop_pg = SOCKET_STOP_PG; | ||
591 | cm_offset = 0x10000; | ||
592 | } else { | ||
593 | start_pg = PCNET_START_PG; | ||
594 | stop_pg = PCNET_STOP_PG; | ||
595 | cm_offset = 0; | ||
596 | } | ||
597 | |||
598 | /* has_shmem is ignored if use_shmem != -1 */ | ||
599 | if ((use_shmem == 0) || (!has_shmem && (use_shmem == -1)) || | ||
600 | (setup_shmem_window(link, start_pg, stop_pg, cm_offset) != 0)) | ||
601 | setup_dma_config(link, start_pg, stop_pg); | ||
602 | |||
603 | ei_status.name = "NE2000"; | ||
604 | ei_status.word16 = 1; | ||
605 | ei_status.reset_8390 = pcnet_reset_8390; | ||
606 | |||
607 | if (info->flags & (IS_DL10019|IS_DL10022)) | ||
608 | mii_phy_probe(dev); | ||
609 | |||
610 | SET_NETDEV_DEV(dev, &link->dev); | ||
611 | |||
612 | if (register_netdev(dev) != 0) { | ||
613 | pr_notice("register_netdev() failed\n"); | ||
614 | goto failed; | ||
615 | } | ||
616 | |||
617 | if (info->flags & (IS_DL10019|IS_DL10022)) { | ||
618 | u_char id = inb(dev->base_addr + 0x1a); | ||
619 | netdev_info(dev, "NE2000 (DL100%d rev %02x): ", | ||
620 | (info->flags & IS_DL10022) ? 22 : 19, id); | ||
621 | if (info->pna_phy) | ||
622 | pr_cont("PNA, "); | ||
623 | } else { | ||
624 | netdev_info(dev, "NE2000 Compatible: "); | ||
625 | } | ||
626 | pr_cont("io %#3lx, irq %d,", dev->base_addr, dev->irq); | ||
627 | if (info->flags & USE_SHMEM) | ||
628 | pr_cont(" mem %#5lx,", dev->mem_start); | ||
629 | if (info->flags & HAS_MISC_REG) | ||
630 | pr_cont(" %s xcvr,", if_names[dev->if_port]); | ||
631 | pr_cont(" hw_addr %pM\n", dev->dev_addr); | ||
632 | return 0; | ||
633 | |||
634 | failed: | ||
635 | pcnet_release(link); | ||
636 | return -ENODEV; | ||
637 | } /* pcnet_config */ | ||
638 | |||
639 | static void pcnet_release(struct pcmcia_device *link) | ||
640 | { | ||
641 | pcnet_dev_t *info = PRIV(link->priv); | ||
642 | |||
643 | dev_dbg(&link->dev, "pcnet_release\n"); | ||
644 | |||
645 | if (info->flags & USE_SHMEM) | ||
646 | iounmap(info->base); | ||
647 | |||
648 | pcmcia_disable_device(link); | ||
649 | } | ||
650 | |||
651 | static int pcnet_suspend(struct pcmcia_device *link) | ||
652 | { | ||
653 | struct net_device *dev = link->priv; | ||
654 | |||
655 | if (link->open) | ||
656 | netif_device_detach(dev); | ||
657 | |||
658 | return 0; | ||
659 | } | ||
660 | |||
661 | static int pcnet_resume(struct pcmcia_device *link) | ||
662 | { | ||
663 | struct net_device *dev = link->priv; | ||
664 | |||
665 | if (link->open) { | ||
666 | pcnet_reset_8390(dev); | ||
667 | NS8390_init(dev, 1); | ||
668 | netif_device_attach(dev); | ||
669 | } | ||
670 | |||
671 | return 0; | ||
672 | } | ||
673 | |||
674 | |||
675 | /*====================================================================== | ||
676 | |||
677 | MII interface support for DL10019 and DL10022 based cards | ||
678 | |||
679 | On the DL10019, the MII IO direction bit is 0x10; on the DL10022 | ||
680 | it is 0x20. Setting both bits seems to work on both card types. | ||
681 | |||
682 | ======================================================================*/ | ||
683 | |||
684 | #define DLINK_GPIO 0x1c | ||
685 | #define DLINK_DIAG 0x1d | ||
686 | #define DLINK_EEPROM 0x1e | ||
687 | |||
688 | #define MDIO_SHIFT_CLK 0x80 | ||
689 | #define MDIO_DATA_OUT 0x40 | ||
690 | #define MDIO_DIR_WRITE 0x30 | ||
691 | #define MDIO_DATA_WRITE0 (MDIO_DIR_WRITE) | ||
692 | #define MDIO_DATA_WRITE1 (MDIO_DIR_WRITE | MDIO_DATA_OUT) | ||
693 | #define MDIO_DATA_READ 0x10 | ||
694 | #define MDIO_MASK 0x0f | ||
695 | |||
696 | static void mdio_sync(unsigned int addr) | ||
697 | { | ||
698 | int bits, mask = inb(addr) & MDIO_MASK; | ||
699 | for (bits = 0; bits < 32; bits++) { | ||
700 | outb(mask | MDIO_DATA_WRITE1, addr); | ||
701 | outb(mask | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, addr); | ||
702 | } | ||
703 | } | ||
704 | |||
705 | static int mdio_read(unsigned int addr, int phy_id, int loc) | ||
706 | { | ||
707 | u_int cmd = (0x06<<10)|(phy_id<<5)|loc; | ||
708 | int i, retval = 0, mask = inb(addr) & MDIO_MASK; | ||
709 | |||
710 | mdio_sync(addr); | ||
711 | for (i = 13; i >= 0; i--) { | ||
712 | int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0; | ||
713 | outb(mask | dat, addr); | ||
714 | outb(mask | dat | MDIO_SHIFT_CLK, addr); | ||
715 | } | ||
716 | for (i = 19; i > 0; i--) { | ||
717 | outb(mask, addr); | ||
718 | retval = (retval << 1) | ((inb(addr) & MDIO_DATA_READ) != 0); | ||
719 | outb(mask | MDIO_SHIFT_CLK, addr); | ||
720 | } | ||
721 | return (retval>>1) & 0xffff; | ||
722 | } | ||
723 | |||
724 | static void mdio_write(unsigned int addr, int phy_id, int loc, int value) | ||
725 | { | ||
726 | u_int cmd = (0x05<<28)|(phy_id<<23)|(loc<<18)|(1<<17)|value; | ||
727 | int i, mask = inb(addr) & MDIO_MASK; | ||
728 | |||
729 | mdio_sync(addr); | ||
730 | for (i = 31; i >= 0; i--) { | ||
731 | int dat = (cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0; | ||
732 | outb(mask | dat, addr); | ||
733 | outb(mask | dat | MDIO_SHIFT_CLK, addr); | ||
734 | } | ||
735 | for (i = 1; i >= 0; i--) { | ||
736 | outb(mask, addr); | ||
737 | outb(mask | MDIO_SHIFT_CLK, addr); | ||
738 | } | ||
739 | } | ||
740 | |||
741 | /*====================================================================== | ||
742 | |||
743 | EEPROM access routines for DL10019 and DL10022 based cards | ||
744 | |||
745 | ======================================================================*/ | ||
746 | |||
747 | #define EE_EEP 0x40 | ||
748 | #define EE_ASIC 0x10 | ||
749 | #define EE_CS 0x08 | ||
750 | #define EE_CK 0x04 | ||
751 | #define EE_DO 0x02 | ||
752 | #define EE_DI 0x01 | ||
753 | #define EE_ADOT 0x01 /* DataOut for ASIC */ | ||
754 | #define EE_READ_CMD 0x06 | ||
755 | |||
756 | #define DL19FDUPLX 0x0400 /* DL10019 Full duplex mode */ | ||
757 | |||
758 | static int read_eeprom(unsigned int ioaddr, int location) | ||
759 | { | ||
760 | int i, retval = 0; | ||
761 | unsigned int ee_addr = ioaddr + DLINK_EEPROM; | ||
762 | int read_cmd = location | (EE_READ_CMD << 8); | ||
763 | |||
764 | outb(0, ee_addr); | ||
765 | outb(EE_EEP|EE_CS, ee_addr); | ||
766 | |||
767 | /* Shift the read command bits out. */ | ||
768 | for (i = 10; i >= 0; i--) { | ||
769 | short dataval = (read_cmd & (1 << i)) ? EE_DO : 0; | ||
770 | outb_p(EE_EEP|EE_CS|dataval, ee_addr); | ||
771 | outb_p(EE_EEP|EE_CS|dataval|EE_CK, ee_addr); | ||
772 | } | ||
773 | outb(EE_EEP|EE_CS, ee_addr); | ||
774 | |||
775 | for (i = 16; i > 0; i--) { | ||
776 | outb_p(EE_EEP|EE_CS | EE_CK, ee_addr); | ||
777 | retval = (retval << 1) | ((inb(ee_addr) & EE_DI) ? 1 : 0); | ||
778 | outb_p(EE_EEP|EE_CS, ee_addr); | ||
779 | } | ||
780 | |||
781 | /* Terminate the EEPROM access. */ | ||
782 | outb(0, ee_addr); | ||
783 | return retval; | ||
784 | } | ||
785 | |||
786 | /* | ||
787 | The internal ASIC registers can be changed by EEPROM READ access | ||
788 | with EE_ASIC bit set. | ||
789 | In ASIC mode, EE_ADOT is used to output the data to the ASIC. | ||
790 | */ | ||
791 | |||
792 | static void write_asic(unsigned int ioaddr, int location, short asic_data) | ||
793 | { | ||
794 | int i; | ||
795 | unsigned int ee_addr = ioaddr + DLINK_EEPROM; | ||
796 | short dataval; | ||
797 | int read_cmd = location | (EE_READ_CMD << 8); | ||
798 | |||
799 | asic_data |= read_eeprom(ioaddr, location); | ||
800 | |||
801 | outb(0, ee_addr); | ||
802 | outb(EE_ASIC|EE_CS|EE_DI, ee_addr); | ||
803 | |||
804 | read_cmd = read_cmd >> 1; | ||
805 | |||
806 | /* Shift the read command bits out. */ | ||
807 | for (i = 9; i >= 0; i--) { | ||
808 | dataval = (read_cmd & (1 << i)) ? EE_DO : 0; | ||
809 | outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr); | ||
810 | outb_p(EE_ASIC|EE_CS|EE_DI|dataval|EE_CK, ee_addr); | ||
811 | outb_p(EE_ASIC|EE_CS|EE_DI|dataval, ee_addr); | ||
812 | } | ||
813 | // sync | ||
814 | outb(EE_ASIC|EE_CS, ee_addr); | ||
815 | outb(EE_ASIC|EE_CS|EE_CK, ee_addr); | ||
816 | outb(EE_ASIC|EE_CS, ee_addr); | ||
817 | |||
818 | for (i = 15; i >= 0; i--) { | ||
819 | dataval = (asic_data & (1 << i)) ? EE_ADOT : 0; | ||
820 | outb_p(EE_ASIC|EE_CS|dataval, ee_addr); | ||
821 | outb_p(EE_ASIC|EE_CS|dataval|EE_CK, ee_addr); | ||
822 | outb_p(EE_ASIC|EE_CS|dataval, ee_addr); | ||
823 | } | ||
824 | |||
825 | /* Terminate the ASIC access. */ | ||
826 | outb(EE_ASIC|EE_DI, ee_addr); | ||
827 | outb(EE_ASIC|EE_DI| EE_CK, ee_addr); | ||
828 | outb(EE_ASIC|EE_DI, ee_addr); | ||
829 | |||
830 | outb(0, ee_addr); | ||
831 | } | ||
832 | |||
833 | /*====================================================================*/ | ||
834 | |||
835 | static void set_misc_reg(struct net_device *dev) | ||
836 | { | ||
837 | unsigned int nic_base = dev->base_addr; | ||
838 | pcnet_dev_t *info = PRIV(dev); | ||
839 | u_char tmp; | ||
840 | |||
841 | if (info->flags & HAS_MISC_REG) { | ||
842 | tmp = inb_p(nic_base + PCNET_MISC) & ~3; | ||
843 | if (dev->if_port == 2) | ||
844 | tmp |= 1; | ||
845 | if (info->flags & USE_BIG_BUF) | ||
846 | tmp |= 2; | ||
847 | if (info->flags & HAS_IBM_MISC) | ||
848 | tmp |= 8; | ||
849 | outb_p(tmp, nic_base + PCNET_MISC); | ||
850 | } | ||
851 | if (info->flags & IS_DL10022) { | ||
852 | if (info->flags & HAS_MII) { | ||
853 | /* Advertise 100F, 100H, 10F, 10H */ | ||
854 | mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 4, 0x01e1); | ||
855 | /* Restart MII autonegotiation */ | ||
856 | mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000); | ||
857 | mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200); | ||
858 | info->mii_reset = jiffies; | ||
859 | } else { | ||
860 | outb(full_duplex ? 4 : 0, nic_base + DLINK_DIAG); | ||
861 | } | ||
862 | } else if (info->flags & IS_DL10019) { | ||
863 | /* Advertise 100F, 100H, 10F, 10H */ | ||
864 | mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 4, 0x01e1); | ||
865 | /* Restart MII autonegotiation */ | ||
866 | mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000); | ||
867 | mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200); | ||
868 | } | ||
869 | } | ||
870 | |||
871 | /*====================================================================*/ | ||
872 | |||
873 | static void mii_phy_probe(struct net_device *dev) | ||
874 | { | ||
875 | pcnet_dev_t *info = PRIV(dev); | ||
876 | unsigned int mii_addr = dev->base_addr + DLINK_GPIO; | ||
877 | int i; | ||
878 | u_int tmp, phyid; | ||
879 | |||
880 | for (i = 31; i >= 0; i--) { | ||
881 | tmp = mdio_read(mii_addr, i, 1); | ||
882 | if ((tmp == 0) || (tmp == 0xffff)) | ||
883 | continue; | ||
884 | tmp = mdio_read(mii_addr, i, MII_PHYID_REG1); | ||
885 | phyid = tmp << 16; | ||
886 | phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2); | ||
887 | phyid &= MII_PHYID_REV_MASK; | ||
888 | netdev_dbg(dev, "MII at %d is 0x%08x\n", i, phyid); | ||
889 | if (phyid == AM79C9XX_HOME_PHY) { | ||
890 | info->pna_phy = i; | ||
891 | } else if (phyid != AM79C9XX_ETH_PHY) { | ||
892 | info->eth_phy = i; | ||
893 | } | ||
894 | } | ||
895 | } | ||
896 | |||
897 | static int pcnet_open(struct net_device *dev) | ||
898 | { | ||
899 | int ret; | ||
900 | pcnet_dev_t *info = PRIV(dev); | ||
901 | struct pcmcia_device *link = info->p_dev; | ||
902 | unsigned int nic_base = dev->base_addr; | ||
903 | |||
904 | dev_dbg(&link->dev, "pcnet_open('%s')\n", dev->name); | ||
905 | |||
906 | if (!pcmcia_dev_present(link)) | ||
907 | return -ENODEV; | ||
908 | |||
909 | set_misc_reg(dev); | ||
910 | |||
911 | outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */ | ||
912 | ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev->name, dev); | ||
913 | if (ret) | ||
914 | return ret; | ||
915 | |||
916 | link->open++; | ||
917 | |||
918 | info->phy_id = info->eth_phy; | ||
919 | info->link_status = 0x00; | ||
920 | init_timer(&info->watchdog); | ||
921 | info->watchdog.function = ei_watchdog; | ||
922 | info->watchdog.data = (u_long)dev; | ||
923 | info->watchdog.expires = jiffies + HZ; | ||
924 | add_timer(&info->watchdog); | ||
925 | |||
926 | return ei_open(dev); | ||
927 | } /* pcnet_open */ | ||
928 | |||
929 | /*====================================================================*/ | ||
930 | |||
931 | static int pcnet_close(struct net_device *dev) | ||
932 | { | ||
933 | pcnet_dev_t *info = PRIV(dev); | ||
934 | struct pcmcia_device *link = info->p_dev; | ||
935 | |||
936 | dev_dbg(&link->dev, "pcnet_close('%s')\n", dev->name); | ||
937 | |||
938 | ei_close(dev); | ||
939 | free_irq(dev->irq, dev); | ||
940 | |||
941 | link->open--; | ||
942 | netif_stop_queue(dev); | ||
943 | del_timer_sync(&info->watchdog); | ||
944 | |||
945 | return 0; | ||
946 | } /* pcnet_close */ | ||
947 | |||
948 | /*====================================================================== | ||
949 | |||
950 | Hard reset the card. This used to pause for the same period that | ||
951 | a 8390 reset command required, but that shouldn't be necessary. | ||
952 | |||
953 | ======================================================================*/ | ||
954 | |||
955 | static void pcnet_reset_8390(struct net_device *dev) | ||
956 | { | ||
957 | unsigned int nic_base = dev->base_addr; | ||
958 | int i; | ||
959 | |||
960 | ei_status.txing = ei_status.dmaing = 0; | ||
961 | |||
962 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, nic_base + E8390_CMD); | ||
963 | |||
964 | outb(inb(nic_base + PCNET_RESET), nic_base + PCNET_RESET); | ||
965 | |||
966 | for (i = 0; i < 100; i++) { | ||
967 | if ((inb_p(nic_base+EN0_ISR) & ENISR_RESET) != 0) | ||
968 | break; | ||
969 | udelay(100); | ||
970 | } | ||
971 | outb_p(ENISR_RESET, nic_base + EN0_ISR); /* Ack intr. */ | ||
972 | |||
973 | if (i == 100) | ||
974 | netdev_err(dev, "pcnet_reset_8390() did not complete.\n"); | ||
975 | |||
976 | set_misc_reg(dev); | ||
977 | |||
978 | } /* pcnet_reset_8390 */ | ||
979 | |||
980 | /*====================================================================*/ | ||
981 | |||
982 | static int set_config(struct net_device *dev, struct ifmap *map) | ||
983 | { | ||
984 | pcnet_dev_t *info = PRIV(dev); | ||
985 | if ((map->port != (u_char)(-1)) && (map->port != dev->if_port)) { | ||
986 | if (!(info->flags & HAS_MISC_REG)) | ||
987 | return -EOPNOTSUPP; | ||
988 | else if ((map->port < 1) || (map->port > 2)) | ||
989 | return -EINVAL; | ||
990 | dev->if_port = map->port; | ||
991 | netdev_info(dev, "switched to %s port\n", if_names[dev->if_port]); | ||
992 | NS8390_init(dev, 1); | ||
993 | } | ||
994 | return 0; | ||
995 | } | ||
996 | |||
997 | /*====================================================================*/ | ||
998 | |||
999 | static irqreturn_t ei_irq_wrapper(int irq, void *dev_id) | ||
1000 | { | ||
1001 | struct net_device *dev = dev_id; | ||
1002 | pcnet_dev_t *info; | ||
1003 | irqreturn_t ret = ei_interrupt(irq, dev_id); | ||
1004 | |||
1005 | if (ret == IRQ_HANDLED) { | ||
1006 | info = PRIV(dev); | ||
1007 | info->stale = 0; | ||
1008 | } | ||
1009 | return ret; | ||
1010 | } | ||
1011 | |||
1012 | static void ei_watchdog(u_long arg) | ||
1013 | { | ||
1014 | struct net_device *dev = (struct net_device *)arg; | ||
1015 | pcnet_dev_t *info = PRIV(dev); | ||
1016 | unsigned int nic_base = dev->base_addr; | ||
1017 | unsigned int mii_addr = nic_base + DLINK_GPIO; | ||
1018 | u_short link; | ||
1019 | |||
1020 | if (!netif_device_present(dev)) goto reschedule; | ||
1021 | |||
1022 | /* Check for pending interrupt with expired latency timer: with | ||
1023 | this, we can limp along even if the interrupt is blocked */ | ||
1024 | if (info->stale++ && (inb_p(nic_base + EN0_ISR) & ENISR_ALL)) { | ||
1025 | if (!info->fast_poll) | ||
1026 | netdev_info(dev, "interrupt(s) dropped!\n"); | ||
1027 | ei_irq_wrapper(dev->irq, dev); | ||
1028 | info->fast_poll = HZ; | ||
1029 | } | ||
1030 | if (info->fast_poll) { | ||
1031 | info->fast_poll--; | ||
1032 | info->watchdog.expires = jiffies + 1; | ||
1033 | add_timer(&info->watchdog); | ||
1034 | return; | ||
1035 | } | ||
1036 | |||
1037 | if (!(info->flags & HAS_MII)) | ||
1038 | goto reschedule; | ||
1039 | |||
1040 | mdio_read(mii_addr, info->phy_id, 1); | ||
1041 | link = mdio_read(mii_addr, info->phy_id, 1); | ||
1042 | if (!link || (link == 0xffff)) { | ||
1043 | if (info->eth_phy) { | ||
1044 | info->phy_id = info->eth_phy = 0; | ||
1045 | } else { | ||
1046 | netdev_info(dev, "MII is missing!\n"); | ||
1047 | info->flags &= ~HAS_MII; | ||
1048 | } | ||
1049 | goto reschedule; | ||
1050 | } | ||
1051 | |||
1052 | link &= 0x0004; | ||
1053 | if (link != info->link_status) { | ||
1054 | u_short p = mdio_read(mii_addr, info->phy_id, 5); | ||
1055 | netdev_info(dev, "%s link beat\n", link ? "found" : "lost"); | ||
1056 | if (link && (info->flags & IS_DL10022)) { | ||
1057 | /* Disable collision detection on full duplex links */ | ||
1058 | outb((p & 0x0140) ? 4 : 0, nic_base + DLINK_DIAG); | ||
1059 | } else if (link && (info->flags & IS_DL10019)) { | ||
1060 | /* Disable collision detection on full duplex links */ | ||
1061 | write_asic(dev->base_addr, 4, (p & 0x140) ? DL19FDUPLX : 0); | ||
1062 | } | ||
1063 | if (link) { | ||
1064 | if (info->phy_id == info->eth_phy) { | ||
1065 | if (p) | ||
1066 | netdev_info(dev, "autonegotiation complete: " | ||
1067 | "%sbaseT-%cD selected\n", | ||
1068 | ((p & 0x0180) ? "100" : "10"), | ||
1069 | ((p & 0x0140) ? 'F' : 'H')); | ||
1070 | else | ||
1071 | netdev_info(dev, "link partner did not autonegotiate\n"); | ||
1072 | } | ||
1073 | NS8390_init(dev, 1); | ||
1074 | } | ||
1075 | info->link_status = link; | ||
1076 | } | ||
1077 | if (info->pna_phy && time_after(jiffies, info->mii_reset + 6*HZ)) { | ||
1078 | link = mdio_read(mii_addr, info->eth_phy, 1) & 0x0004; | ||
1079 | if (((info->phy_id == info->pna_phy) && link) || | ||
1080 | ((info->phy_id != info->pna_phy) && !link)) { | ||
1081 | /* isolate this MII and try flipping to the other one */ | ||
1082 | mdio_write(mii_addr, info->phy_id, 0, 0x0400); | ||
1083 | info->phy_id ^= info->pna_phy ^ info->eth_phy; | ||
1084 | netdev_info(dev, "switched to %s transceiver\n", | ||
1085 | (info->phy_id == info->eth_phy) ? "ethernet" : "PNA"); | ||
1086 | mdio_write(mii_addr, info->phy_id, 0, | ||
1087 | (info->phy_id == info->eth_phy) ? 0x1000 : 0); | ||
1088 | info->link_status = 0; | ||
1089 | info->mii_reset = jiffies; | ||
1090 | } | ||
1091 | } | ||
1092 | |||
1093 | reschedule: | ||
1094 | info->watchdog.expires = jiffies + HZ; | ||
1095 | add_timer(&info->watchdog); | ||
1096 | } | ||
1097 | |||
1098 | /*====================================================================*/ | ||
1099 | |||
1100 | |||
1101 | static int ei_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | ||
1102 | { | ||
1103 | pcnet_dev_t *info = PRIV(dev); | ||
1104 | struct mii_ioctl_data *data = if_mii(rq); | ||
1105 | unsigned int mii_addr = dev->base_addr + DLINK_GPIO; | ||
1106 | |||
1107 | if (!(info->flags & (IS_DL10019|IS_DL10022))) | ||
1108 | return -EINVAL; | ||
1109 | |||
1110 | switch (cmd) { | ||
1111 | case SIOCGMIIPHY: | ||
1112 | data->phy_id = info->phy_id; | ||
1113 | case SIOCGMIIREG: /* Read MII PHY register. */ | ||
1114 | data->val_out = mdio_read(mii_addr, data->phy_id, data->reg_num & 0x1f); | ||
1115 | return 0; | ||
1116 | case SIOCSMIIREG: /* Write MII PHY register. */ | ||
1117 | mdio_write(mii_addr, data->phy_id, data->reg_num & 0x1f, data->val_in); | ||
1118 | return 0; | ||
1119 | } | ||
1120 | return -EOPNOTSUPP; | ||
1121 | } | ||
1122 | |||
1123 | /*====================================================================*/ | ||
1124 | |||
1125 | static void dma_get_8390_hdr(struct net_device *dev, | ||
1126 | struct e8390_pkt_hdr *hdr, | ||
1127 | int ring_page) | ||
1128 | { | ||
1129 | unsigned int nic_base = dev->base_addr; | ||
1130 | |||
1131 | if (ei_status.dmaing) { | ||
1132 | netdev_notice(dev, "DMAing conflict in dma_block_input." | ||
1133 | "[DMAstat:%1x][irqlock:%1x]\n", | ||
1134 | ei_status.dmaing, ei_status.irqlock); | ||
1135 | return; | ||
1136 | } | ||
1137 | |||
1138 | ei_status.dmaing |= 0x01; | ||
1139 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD); | ||
1140 | outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO); | ||
1141 | outb_p(0, nic_base + EN0_RCNTHI); | ||
1142 | outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */ | ||
1143 | outb_p(ring_page, nic_base + EN0_RSARHI); | ||
1144 | outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD); | ||
1145 | |||
1146 | insw(nic_base + PCNET_DATAPORT, hdr, | ||
1147 | sizeof(struct e8390_pkt_hdr)>>1); | ||
1148 | /* Fix for big endian systems */ | ||
1149 | hdr->count = le16_to_cpu(hdr->count); | ||
1150 | |||
1151 | outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
1152 | ei_status.dmaing &= ~0x01; | ||
1153 | } | ||
1154 | |||
1155 | /*====================================================================*/ | ||
1156 | |||
1157 | static void dma_block_input(struct net_device *dev, int count, | ||
1158 | struct sk_buff *skb, int ring_offset) | ||
1159 | { | ||
1160 | unsigned int nic_base = dev->base_addr; | ||
1161 | int xfer_count = count; | ||
1162 | char *buf = skb->data; | ||
1163 | |||
1164 | if ((ei_debug > 4) && (count != 4)) | ||
1165 | netdev_dbg(dev, "[bi=%d]\n", count+4); | ||
1166 | if (ei_status.dmaing) { | ||
1167 | netdev_notice(dev, "DMAing conflict in dma_block_input." | ||
1168 | "[DMAstat:%1x][irqlock:%1x]\n", | ||
1169 | ei_status.dmaing, ei_status.irqlock); | ||
1170 | return; | ||
1171 | } | ||
1172 | ei_status.dmaing |= 0x01; | ||
1173 | outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base + PCNET_CMD); | ||
1174 | outb_p(count & 0xff, nic_base + EN0_RCNTLO); | ||
1175 | outb_p(count >> 8, nic_base + EN0_RCNTHI); | ||
1176 | outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO); | ||
1177 | outb_p(ring_offset >> 8, nic_base + EN0_RSARHI); | ||
1178 | outb_p(E8390_RREAD+E8390_START, nic_base + PCNET_CMD); | ||
1179 | |||
1180 | insw(nic_base + PCNET_DATAPORT,buf,count>>1); | ||
1181 | if (count & 0x01) | ||
1182 | buf[count-1] = inb(nic_base + PCNET_DATAPORT), xfer_count++; | ||
1183 | |||
1184 | /* This was for the ALPHA version only, but enough people have been | ||
1185 | encountering problems that it is still here. */ | ||
1186 | #ifdef PCMCIA_DEBUG | ||
1187 | if (ei_debug > 4) { /* DMA termination address check... */ | ||
1188 | int addr, tries = 20; | ||
1189 | do { | ||
1190 | /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here | ||
1191 | -- it's broken for Rx on some cards! */ | ||
1192 | int high = inb_p(nic_base + EN0_RSARHI); | ||
1193 | int low = inb_p(nic_base + EN0_RSARLO); | ||
1194 | addr = (high << 8) + low; | ||
1195 | if (((ring_offset + xfer_count) & 0xff) == (addr & 0xff)) | ||
1196 | break; | ||
1197 | } while (--tries > 0); | ||
1198 | if (tries <= 0) | ||
1199 | netdev_notice(dev, "RX transfer address mismatch," | ||
1200 | "%#4.4x (expected) vs. %#4.4x (actual).\n", | ||
1201 | ring_offset + xfer_count, addr); | ||
1202 | } | ||
1203 | #endif | ||
1204 | outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
1205 | ei_status.dmaing &= ~0x01; | ||
1206 | } /* dma_block_input */ | ||
1207 | |||
1208 | /*====================================================================*/ | ||
1209 | |||
1210 | static void dma_block_output(struct net_device *dev, int count, | ||
1211 | const u_char *buf, const int start_page) | ||
1212 | { | ||
1213 | unsigned int nic_base = dev->base_addr; | ||
1214 | pcnet_dev_t *info = PRIV(dev); | ||
1215 | #ifdef PCMCIA_DEBUG | ||
1216 | int retries = 0; | ||
1217 | #endif | ||
1218 | u_long dma_start; | ||
1219 | |||
1220 | #ifdef PCMCIA_DEBUG | ||
1221 | if (ei_debug > 4) | ||
1222 | netdev_dbg(dev, "[bo=%d]\n", count); | ||
1223 | #endif | ||
1224 | |||
1225 | /* Round the count up for word writes. Do we need to do this? | ||
1226 | What effect will an odd byte count have on the 8390? | ||
1227 | I should check someday. */ | ||
1228 | if (count & 0x01) | ||
1229 | count++; | ||
1230 | if (ei_status.dmaing) { | ||
1231 | netdev_notice(dev, "DMAing conflict in dma_block_output." | ||
1232 | "[DMAstat:%1x][irqlock:%1x]\n", | ||
1233 | ei_status.dmaing, ei_status.irqlock); | ||
1234 | return; | ||
1235 | } | ||
1236 | ei_status.dmaing |= 0x01; | ||
1237 | /* We should already be in page 0, but to be safe... */ | ||
1238 | outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base+PCNET_CMD); | ||
1239 | |||
1240 | #ifdef PCMCIA_DEBUG | ||
1241 | retry: | ||
1242 | #endif | ||
1243 | |||
1244 | outb_p(ENISR_RDC, nic_base + EN0_ISR); | ||
1245 | |||
1246 | /* Now the normal output. */ | ||
1247 | outb_p(count & 0xff, nic_base + EN0_RCNTLO); | ||
1248 | outb_p(count >> 8, nic_base + EN0_RCNTHI); | ||
1249 | outb_p(0x00, nic_base + EN0_RSARLO); | ||
1250 | outb_p(start_page, nic_base + EN0_RSARHI); | ||
1251 | |||
1252 | outb_p(E8390_RWRITE+E8390_START, nic_base + PCNET_CMD); | ||
1253 | outsw(nic_base + PCNET_DATAPORT, buf, count>>1); | ||
1254 | |||
1255 | dma_start = jiffies; | ||
1256 | |||
1257 | #ifdef PCMCIA_DEBUG | ||
1258 | /* This was for the ALPHA version only, but enough people have been | ||
1259 | encountering problems that it is still here. */ | ||
1260 | if (ei_debug > 4) { /* DMA termination address check... */ | ||
1261 | int addr, tries = 20; | ||
1262 | do { | ||
1263 | int high = inb_p(nic_base + EN0_RSARHI); | ||
1264 | int low = inb_p(nic_base + EN0_RSARLO); | ||
1265 | addr = (high << 8) + low; | ||
1266 | if ((start_page << 8) + count == addr) | ||
1267 | break; | ||
1268 | } while (--tries > 0); | ||
1269 | if (tries <= 0) { | ||
1270 | netdev_notice(dev, "Tx packet transfer address mismatch," | ||
1271 | "%#4.4x (expected) vs. %#4.4x (actual).\n", | ||
1272 | (start_page << 8) + count, addr); | ||
1273 | if (retries++ == 0) | ||
1274 | goto retry; | ||
1275 | } | ||
1276 | } | ||
1277 | #endif | ||
1278 | |||
1279 | while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0) | ||
1280 | if (time_after(jiffies, dma_start + PCNET_RDC_TIMEOUT)) { | ||
1281 | netdev_notice(dev, "timeout waiting for Tx RDC.\n"); | ||
1282 | pcnet_reset_8390(dev); | ||
1283 | NS8390_init(dev, 1); | ||
1284 | break; | ||
1285 | } | ||
1286 | |||
1287 | outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */ | ||
1288 | if (info->flags & DELAY_OUTPUT) | ||
1289 | udelay((long)delay_time); | ||
1290 | ei_status.dmaing &= ~0x01; | ||
1291 | } | ||
1292 | |||
1293 | /*====================================================================*/ | ||
1294 | |||
1295 | static int setup_dma_config(struct pcmcia_device *link, int start_pg, | ||
1296 | int stop_pg) | ||
1297 | { | ||
1298 | struct net_device *dev = link->priv; | ||
1299 | |||
1300 | ei_status.tx_start_page = start_pg; | ||
1301 | ei_status.rx_start_page = start_pg + TX_PAGES; | ||
1302 | ei_status.stop_page = stop_pg; | ||
1303 | |||
1304 | /* set up block i/o functions */ | ||
1305 | ei_status.get_8390_hdr = dma_get_8390_hdr; | ||
1306 | ei_status.block_input = dma_block_input; | ||
1307 | ei_status.block_output = dma_block_output; | ||
1308 | |||
1309 | return 0; | ||
1310 | } | ||
1311 | |||
1312 | /*====================================================================*/ | ||
1313 | |||
1314 | static void copyin(void *dest, void __iomem *src, int c) | ||
1315 | { | ||
1316 | u_short *d = dest; | ||
1317 | u_short __iomem *s = src; | ||
1318 | int odd; | ||
1319 | |||
1320 | if (c <= 0) | ||
1321 | return; | ||
1322 | odd = (c & 1); c >>= 1; | ||
1323 | |||
1324 | if (c) { | ||
1325 | do { *d++ = __raw_readw(s++); } while (--c); | ||
1326 | } | ||
1327 | /* get last byte by fetching a word and masking */ | ||
1328 | if (odd) | ||
1329 | *((u_char *)d) = readw(s) & 0xff; | ||
1330 | } | ||
1331 | |||
1332 | static void copyout(void __iomem *dest, const void *src, int c) | ||
1333 | { | ||
1334 | u_short __iomem *d = dest; | ||
1335 | const u_short *s = src; | ||
1336 | int odd; | ||
1337 | |||
1338 | if (c <= 0) | ||
1339 | return; | ||
1340 | odd = (c & 1); c >>= 1; | ||
1341 | |||
1342 | if (c) { | ||
1343 | do { __raw_writew(*s++, d++); } while (--c); | ||
1344 | } | ||
1345 | /* copy last byte doing a read-modify-write */ | ||
1346 | if (odd) | ||
1347 | writew((readw(d) & 0xff00) | *(u_char *)s, d); | ||
1348 | } | ||
1349 | |||
1350 | /*====================================================================*/ | ||
1351 | |||
1352 | static void shmem_get_8390_hdr(struct net_device *dev, | ||
1353 | struct e8390_pkt_hdr *hdr, | ||
1354 | int ring_page) | ||
1355 | { | ||
1356 | void __iomem *xfer_start = ei_status.mem + (TX_PAGES<<8) | ||
1357 | + (ring_page << 8) | ||
1358 | - (ei_status.rx_start_page << 8); | ||
1359 | |||
1360 | copyin(hdr, xfer_start, sizeof(struct e8390_pkt_hdr)); | ||
1361 | /* Fix for big endian systems */ | ||
1362 | hdr->count = le16_to_cpu(hdr->count); | ||
1363 | } | ||
1364 | |||
1365 | /*====================================================================*/ | ||
1366 | |||
1367 | static void shmem_block_input(struct net_device *dev, int count, | ||
1368 | struct sk_buff *skb, int ring_offset) | ||
1369 | { | ||
1370 | void __iomem *base = ei_status.mem; | ||
1371 | unsigned long offset = (TX_PAGES<<8) + ring_offset | ||
1372 | - (ei_status.rx_start_page << 8); | ||
1373 | char *buf = skb->data; | ||
1374 | |||
1375 | if (offset + count > ei_status.priv) { | ||
1376 | /* We must wrap the input move. */ | ||
1377 | int semi_count = ei_status.priv - offset; | ||
1378 | copyin(buf, base + offset, semi_count); | ||
1379 | buf += semi_count; | ||
1380 | offset = TX_PAGES<<8; | ||
1381 | count -= semi_count; | ||
1382 | } | ||
1383 | copyin(buf, base + offset, count); | ||
1384 | } | ||
1385 | |||
1386 | /*====================================================================*/ | ||
1387 | |||
1388 | static void shmem_block_output(struct net_device *dev, int count, | ||
1389 | const u_char *buf, const int start_page) | ||
1390 | { | ||
1391 | void __iomem *shmem = ei_status.mem + (start_page << 8); | ||
1392 | shmem -= ei_status.tx_start_page << 8; | ||
1393 | copyout(shmem, buf, count); | ||
1394 | } | ||
1395 | |||
1396 | /*====================================================================*/ | ||
1397 | |||
1398 | static int setup_shmem_window(struct pcmcia_device *link, int start_pg, | ||
1399 | int stop_pg, int cm_offset) | ||
1400 | { | ||
1401 | struct net_device *dev = link->priv; | ||
1402 | pcnet_dev_t *info = PRIV(dev); | ||
1403 | int i, window_size, offset, ret; | ||
1404 | |||
1405 | window_size = (stop_pg - start_pg) << 8; | ||
1406 | if (window_size > 32 * 1024) | ||
1407 | window_size = 32 * 1024; | ||
1408 | |||
1409 | /* Make sure it's a power of two. */ | ||
1410 | window_size = roundup_pow_of_two(window_size); | ||
1411 | |||
1412 | /* Allocate a memory window */ | ||
1413 | link->resource[3]->flags |= WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM|WIN_ENABLE; | ||
1414 | link->resource[3]->flags |= WIN_USE_WAIT; | ||
1415 | link->resource[3]->start = 0; link->resource[3]->end = window_size; | ||
1416 | ret = pcmcia_request_window(link, link->resource[3], mem_speed); | ||
1417 | if (ret) | ||
1418 | goto failed; | ||
1419 | |||
1420 | offset = (start_pg << 8) + cm_offset; | ||
1421 | offset -= offset % window_size; | ||
1422 | ret = pcmcia_map_mem_page(link, link->resource[3], offset); | ||
1423 | if (ret) | ||
1424 | goto failed; | ||
1425 | |||
1426 | /* Try scribbling on the buffer */ | ||
1427 | info->base = ioremap(link->resource[3]->start, | ||
1428 | resource_size(link->resource[3])); | ||
1429 | for (i = 0; i < (TX_PAGES<<8); i += 2) | ||
1430 | __raw_writew((i>>1), info->base+offset+i); | ||
1431 | udelay(100); | ||
1432 | for (i = 0; i < (TX_PAGES<<8); i += 2) | ||
1433 | if (__raw_readw(info->base+offset+i) != (i>>1)) break; | ||
1434 | pcnet_reset_8390(dev); | ||
1435 | if (i != (TX_PAGES<<8)) { | ||
1436 | iounmap(info->base); | ||
1437 | pcmcia_release_window(link, link->resource[3]); | ||
1438 | info->base = NULL; | ||
1439 | goto failed; | ||
1440 | } | ||
1441 | |||
1442 | ei_status.mem = info->base + offset; | ||
1443 | ei_status.priv = resource_size(link->resource[3]); | ||
1444 | dev->mem_start = (u_long)ei_status.mem; | ||
1445 | dev->mem_end = dev->mem_start + resource_size(link->resource[3]); | ||
1446 | |||
1447 | ei_status.tx_start_page = start_pg; | ||
1448 | ei_status.rx_start_page = start_pg + TX_PAGES; | ||
1449 | ei_status.stop_page = start_pg + ( | ||
1450 | (resource_size(link->resource[3]) - offset) >> 8); | ||
1451 | |||
1452 | /* set up block i/o functions */ | ||
1453 | ei_status.get_8390_hdr = shmem_get_8390_hdr; | ||
1454 | ei_status.block_input = shmem_block_input; | ||
1455 | ei_status.block_output = shmem_block_output; | ||
1456 | |||
1457 | info->flags |= USE_SHMEM; | ||
1458 | return 0; | ||
1459 | |||
1460 | failed: | ||
1461 | return 1; | ||
1462 | } | ||
1463 | |||
1464 | /*====================================================================*/ | ||
1465 | |||
1466 | static const struct pcmcia_device_id pcnet_ids[] = { | ||
1467 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0057, 0x0021), | ||
1468 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0104, 0x000a), | ||
1469 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0xea15), | ||
1470 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0143, 0x3341), | ||
1471 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0143, 0xc0ab), | ||
1472 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x021b, 0x0101), | ||
1473 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x08a1, 0xc0ab), | ||
1474 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "AnyCom", "Fast Ethernet + 56K COMBO", 0x578ba6e7, 0xb0ac62c4), | ||
1475 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "ATKK", "LM33-PCM-T", 0xba9eb7e2, 0x077c174e), | ||
1476 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "D-Link", "DME336T", 0x1a424a1c, 0xb23897ff), | ||
1477 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Grey Cell", "GCS3000", 0x2a151fac, 0x48b932ae), | ||
1478 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "Linksys", "EtherFast 10&100 + 56K PC Card (PCMLM56)", 0x0733cc81, 0xb3765033), | ||
1479 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "LINKSYS", "PCMLM336", 0xf7cb0b07, 0x7a821b58), | ||
1480 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "MICRO RESEARCH", "COMBO-L/M-336", 0xb2ced065, 0x3ced0555), | ||
1481 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), | ||
1482 | PCMCIA_PFC_DEVICE_PROD_ID12(0, "PCMCIAs", "LanModem", 0xdcfe12d3, 0xc67c648f), | ||
1483 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "Home and Away 28.8 PC Card ", 0xb569a6e5, 0x5bd4ff2c), | ||
1484 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "Home and Away Credit Card Adapter", 0xb569a6e5, 0x4bdf15c3), | ||
1485 | PCMCIA_MFC_DEVICE_PROD_ID12(0, "IBM", "w95 Home and Away Credit Card ", 0xb569a6e5, 0xae911c15), | ||
1486 | PCMCIA_MFC_DEVICE_PROD_ID123(0, "APEX DATA", "MULTICARD", "ETHERNET-MODEM", 0x11c2da09, 0x7289dc5d, 0xaad95e1f), | ||
1487 | PCMCIA_MFC_DEVICE_PROD_ID2(0, "FAX/Modem/Ethernet Combo Card ", 0x1ed59302), | ||
1488 | PCMCIA_DEVICE_MANF_CARD(0x0057, 0x1004), | ||
1489 | PCMCIA_DEVICE_MANF_CARD(0x0104, 0x000d), | ||
1490 | PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0075), | ||
1491 | PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0145), | ||
1492 | PCMCIA_DEVICE_MANF_CARD(0x0149, 0x0230), | ||
1493 | PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530), | ||
1494 | PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), | ||
1495 | PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110), | ||
1496 | PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041), | ||
1497 | PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452), | ||
1498 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300), | ||
1499 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0307), | ||
1500 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x030a), | ||
1501 | PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1103), | ||
1502 | PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1121), | ||
1503 | PCMCIA_DEVICE_PROD_ID12("2408LAN", "Ethernet", 0x352fff7f, 0x00b2e941), | ||
1504 | PCMCIA_DEVICE_PROD_ID1234("Socket", "CF 10/100 Ethernet Card", "Revision B", "05/11/06", 0xb38bcc2e, 0x4de88352, 0xeaca6c8d, 0x7e57c22e), | ||
1505 | PCMCIA_DEVICE_PROD_ID123("Cardwell", "PCMCIA", "ETHERNET", 0x9533672e, 0x281f1c5d, 0x3ff7175b), | ||
1506 | PCMCIA_DEVICE_PROD_ID123("CNet ", "CN30BC", "ETHERNET", 0x9fe55d3d, 0x85601198, 0x3ff7175b), | ||
1507 | PCMCIA_DEVICE_PROD_ID123("Digital", "Ethernet", "Adapter", 0x9999ab35, 0x00b2e941, 0x4b0d829e), | ||
1508 | PCMCIA_DEVICE_PROD_ID123("Edimax Technology Inc.", "PCMCIA", "Ethernet Card", 0x738a0019, 0x281f1c5d, 0x5e9d92c0), | ||
1509 | PCMCIA_DEVICE_PROD_ID123("EFA ", "EFA207", "ETHERNET", 0x3d294be4, 0xeb9aab6c, 0x3ff7175b), | ||
1510 | PCMCIA_DEVICE_PROD_ID123("I-O DATA", "PCLA", "ETHERNET", 0x1d55d7ec, 0xe4c64d34, 0x3ff7175b), | ||
1511 | PCMCIA_DEVICE_PROD_ID123("IO DATA", "PCLATE", "ETHERNET", 0x547e66dc, 0x6b260753, 0x3ff7175b), | ||
1512 | PCMCIA_DEVICE_PROD_ID123("KingMax Technology Inc.", "EN10-T2", "PCMCIA Ethernet Card", 0x932b7189, 0x699e4436, 0x6f6652e0), | ||
1513 | PCMCIA_DEVICE_PROD_ID123("PCMCIA", "PCMCIA-ETHERNET-CARD", "UE2216", 0x281f1c5d, 0xd4cd2f20, 0xb87add82), | ||
1514 | PCMCIA_DEVICE_PROD_ID123("PCMCIA", "PCMCIA-ETHERNET-CARD", "UE2620", 0x281f1c5d, 0xd4cd2f20, 0x7d3d83a8), | ||
1515 | PCMCIA_DEVICE_PROD_ID1("2412LAN", 0x67f236ab), | ||
1516 | PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2212", 0xdfc6b5b2, 0xcb112a11), | ||
1517 | PCMCIA_DEVICE_PROD_ID12("ACCTON", "EN2216-PCMCIA-ETHERNET", 0xdfc6b5b2, 0x5542bfff), | ||
1518 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA100-PCM-T V2 100/10M LAN PC Card", 0xbb7fbdd7, 0xcd91cc68), | ||
1519 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA100-PCM V2", 0x36634a66, 0xc6d05997), | ||
1520 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis, K.K.", "CentreCOM LA-PCM_V2", 0xbb7fBdd7, 0x28e299f8), | ||
1521 | PCMCIA_DEVICE_PROD_ID12("Allied Telesis K.K.", "LA-PCM V3", 0x36634a66, 0x62241d96), | ||
1522 | PCMCIA_DEVICE_PROD_ID12("AmbiCom", "AMB8010", 0x5070a7f9, 0x82f96e96), | ||
1523 | PCMCIA_DEVICE_PROD_ID12("AmbiCom", "AMB8610", 0x5070a7f9, 0x86741224), | ||
1524 | PCMCIA_DEVICE_PROD_ID12("AmbiCom Inc", "AMB8002", 0x93b15570, 0x75ec3efb), | ||
1525 | PCMCIA_DEVICE_PROD_ID12("AmbiCom Inc", "AMB8002T", 0x93b15570, 0x461c5247), | ||
1526 | PCMCIA_DEVICE_PROD_ID12("AmbiCom Inc", "AMB8010", 0x93b15570, 0x82f96e96), | ||
1527 | PCMCIA_DEVICE_PROD_ID12("AnyCom", "ECO Ethernet", 0x578ba6e7, 0x0a9888c1), | ||
1528 | PCMCIA_DEVICE_PROD_ID12("AnyCom", "ECO Ethernet 10/100", 0x578ba6e7, 0x939fedbd), | ||
1529 | PCMCIA_DEVICE_PROD_ID12("AROWANA", "PCMCIA Ethernet LAN Card", 0x313adbc8, 0x08d9f190), | ||
1530 | PCMCIA_DEVICE_PROD_ID12("ASANTE", "FriendlyNet PC Card", 0x3a7ade0f, 0x41c64504), | ||
1531 | PCMCIA_DEVICE_PROD_ID12("Billionton", "LNT-10TB", 0x552ab682, 0xeeb1ba6a), | ||
1532 | PCMCIA_DEVICE_PROD_ID12("CF", "10Base-Ethernet", 0x44ebf863, 0x93ae4d79), | ||
1533 | PCMCIA_DEVICE_PROD_ID12("CNet", "CN40BC Ethernet", 0xbc477dde, 0xfba775a7), | ||
1534 | PCMCIA_DEVICE_PROD_ID12("COMPU-SHACK", "BASEline PCMCIA 10 MBit Ethernetadapter", 0xfa2e424d, 0xe9190d8a), | ||
1535 | PCMCIA_DEVICE_PROD_ID12("COMPU-SHACK", "FASTline PCMCIA 10/100 Fast-Ethernet", 0xfa2e424d, 0x3953d9b9), | ||
1536 | PCMCIA_DEVICE_PROD_ID12("CONTEC", "C-NET(PC)C-10L", 0x21cab552, 0xf6f90722), | ||
1537 | PCMCIA_DEVICE_PROD_ID12("corega", "FEther PCC-TXF", 0x0a21501a, 0xa51564a2), | ||
1538 | PCMCIA_DEVICE_PROD_ID12("corega", "Ether CF-TD", 0x0a21501a, 0x6589340a), | ||
1539 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether CF-TD LAN Card", 0x5261440f, 0x8797663b), | ||
1540 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-T", 0x5261440f, 0xfa9d85bd), | ||
1541 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-TD", 0x5261440f, 0xc49bd73d), | ||
1542 | PCMCIA_DEVICE_PROD_ID12("Corega K.K.", "corega EtherII PCC-TD", 0xd4fdcbd8, 0xc49bd73d), | ||
1543 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-T", 0x5261440f, 0x6705fcaa), | ||
1544 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-TD", 0x5261440f, 0x47d5ca83), | ||
1545 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FastEther PCC-TX", 0x5261440f, 0x485e85d9), | ||
1546 | PCMCIA_DEVICE_PROD_ID12("Corega,K.K.", "Ethernet LAN Card", 0x110d26d9, 0x9fd2f0a2), | ||
1547 | PCMCIA_DEVICE_PROD_ID12("corega,K.K.", "Ethernet LAN Card", 0x9791a90e, 0x9fd2f0a2), | ||
1548 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "(CG-LAPCCTXD)", 0x5261440f, 0x73ec0d88), | ||
1549 | PCMCIA_DEVICE_PROD_ID12("CouplerlessPCMCIA", "100BASE", 0xee5af0ad, 0x7c2add04), | ||
1550 | PCMCIA_DEVICE_PROD_ID12("CyQ've", "ELA-010", 0x77008979, 0x9d8d445d), | ||
1551 | PCMCIA_DEVICE_PROD_ID12("CyQ've", "ELA-110E 10/100M LAN Card", 0x77008979, 0xfd184814), | ||
1552 | PCMCIA_DEVICE_PROD_ID12("DataTrek.", "NetCard ", 0x5cd66d9d, 0x84697ce0), | ||
1553 | PCMCIA_DEVICE_PROD_ID12("Dayna Communications, Inc.", "CommuniCard E", 0x0c629325, 0xb4e7dbaf), | ||
1554 | PCMCIA_DEVICE_PROD_ID12("Digicom", "Palladio LAN 10/100", 0x697403d8, 0xe160b995), | ||
1555 | PCMCIA_DEVICE_PROD_ID12("Digicom", "Palladio LAN 10/100 Dongless", 0x697403d8, 0xa6d3b233), | ||
1556 | PCMCIA_DEVICE_PROD_ID12("DIGITAL", "DEPCM-XX", 0x69616cb3, 0xe600e76e), | ||
1557 | PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-650", 0x1a424a1c, 0xf28c8398), | ||
1558 | PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660", 0x1a424a1c, 0xd9a1d05b), | ||
1559 | PCMCIA_DEVICE_PROD_ID12("D-Link", "DE-660+", 0x1a424a1c, 0x50dcd0ec), | ||
1560 | PCMCIA_DEVICE_PROD_ID12("D-Link", "DFE-650", 0x1a424a1c, 0x0f0073f9), | ||
1561 | PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 PC Card", 0x725b842d, 0xf1efee84), | ||
1562 | PCMCIA_DEVICE_PROD_ID12("Dual Speed", "10/100 Port Attached PC Card", 0x725b842d, 0x2db1f8e9), | ||
1563 | PCMCIA_DEVICE_PROD_ID12("Dynalink", "L10BC", 0x55632fd5, 0xdc65f2b1), | ||
1564 | PCMCIA_DEVICE_PROD_ID12("DYNALINK", "L10BC", 0x6a26d1cf, 0xdc65f2b1), | ||
1565 | PCMCIA_DEVICE_PROD_ID12("DYNALINK", "L10C", 0x6a26d1cf, 0xc4f84efb), | ||
1566 | PCMCIA_DEVICE_PROD_ID12("E-CARD", "E-CARD", 0x6701da11, 0x6701da11), | ||
1567 | PCMCIA_DEVICE_PROD_ID12("EIGER Labs Inc.", "Ethernet 10BaseT card", 0x53c864c6, 0xedd059f6), | ||
1568 | PCMCIA_DEVICE_PROD_ID12("EIGER Labs Inc.", "Ethernet Combo card", 0x53c864c6, 0x929c486c), | ||
1569 | PCMCIA_DEVICE_PROD_ID12("Ethernet", "Adapter", 0x00b2e941, 0x4b0d829e), | ||
1570 | PCMCIA_DEVICE_PROD_ID12("Ethernet Adapter", "E2000 PCMCIA Ethernet", 0x96767301, 0x71fbbc61), | ||
1571 | PCMCIA_DEVICE_PROD_ID12("Ethernet PCMCIA adapter", "EP-210", 0x8dd86181, 0xf2b52517), | ||
1572 | PCMCIA_DEVICE_PROD_ID12("Fast Ethernet", "Adapter", 0xb4be14e3, 0x4b0d829e), | ||
1573 | PCMCIA_DEVICE_PROD_ID12("Grey Cell", "GCS2000", 0x2a151fac, 0xf00555cb), | ||
1574 | PCMCIA_DEVICE_PROD_ID12("Grey Cell", "GCS2220", 0x2a151fac, 0xc1b7e327), | ||
1575 | PCMCIA_DEVICE_PROD_ID12("GVC", "NIC-2000p", 0x76e171bd, 0x6eb1c947), | ||
1576 | PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "Ethernet", 0xe3736c88, 0x00b2e941), | ||
1577 | PCMCIA_DEVICE_PROD_ID12("IC-CARD", "IC-CARD", 0x60cb09a6, 0x60cb09a6), | ||
1578 | PCMCIA_DEVICE_PROD_ID12("IC-CARD+", "IC-CARD+", 0x93693494, 0x93693494), | ||
1579 | PCMCIA_DEVICE_PROD_ID12("IO DATA", "PCETTX", 0x547e66dc, 0x6fc5459b), | ||
1580 | PCMCIA_DEVICE_PROD_ID12("iPort", "10/100 Ethernet Card", 0x56c538d2, 0x11b0ffc0), | ||
1581 | PCMCIA_DEVICE_PROD_ID12("KANSAI ELECTRIC CO.,LTD", "KLA-PCM/T", 0xb18dc3b4, 0xcc51a956), | ||
1582 | PCMCIA_DEVICE_PROD_ID12("KENTRONICS", "KEP-230", 0xaf8144c9, 0x868f6616), | ||
1583 | PCMCIA_DEVICE_PROD_ID12("KCI", "PE520 PCMCIA Ethernet Adapter", 0xa89b87d3, 0x1eb88e64), | ||
1584 | PCMCIA_DEVICE_PROD_ID12("KINGMAX", "EN10T2T", 0x7bcb459a, 0xa5c81fa5), | ||
1585 | PCMCIA_DEVICE_PROD_ID12("Kingston", "KNE-PC2", 0x1128e633, 0xce2a89b3), | ||
1586 | PCMCIA_DEVICE_PROD_ID12("Kingston Technology Corp.", "EtheRx PC Card Ethernet Adapter", 0x313c7be3, 0x0afb54a2), | ||
1587 | PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-10/100CD", 0x1b7827b2, 0xcda71d1c), | ||
1588 | PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDF", 0x1b7827b2, 0xfec71e40), | ||
1589 | PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDL/T", 0x1b7827b2, 0x79fba4f7), | ||
1590 | PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDS", 0x1b7827b2, 0x931afaab), | ||
1591 | PCMCIA_DEVICE_PROD_ID12("LEMEL", "LM-N89TX PRO", 0xbbefb52f, 0xd2897a97), | ||
1592 | PCMCIA_DEVICE_PROD_ID12("Linksys", "Combo PCMCIA EthernetCard (EC2T)", 0x0733cc81, 0x32ee8c78), | ||
1593 | PCMCIA_DEVICE_PROD_ID12("LINKSYS", "E-CARD", 0xf7cb0b07, 0x6701da11), | ||
1594 | PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 Integrated PC Card (PCM100)", 0x0733cc81, 0x453c3f9d), | ||
1595 | PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100)", 0x0733cc81, 0x66c5a389), | ||
1596 | PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 PC Card (PCMPC100 V2)", 0x0733cc81, 0x3a3b28e9), | ||
1597 | PCMCIA_DEVICE_PROD_ID12("Linksys", "HomeLink Phoneline + 10/100 Network PC Card (PCM100H1)", 0x733cc81, 0x7a3e5c3a), | ||
1598 | PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TX", 0x88fcdeda, 0x6d772737), | ||
1599 | PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN100TE", 0x88fcdeda, 0x0e714bee), | ||
1600 | PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN20T", 0x88fcdeda, 0x81090922), | ||
1601 | PCMCIA_DEVICE_PROD_ID12("Logitec", "LPM-LN10TE", 0x88fcdeda, 0xc1e2521c), | ||
1602 | PCMCIA_DEVICE_PROD_ID12("LONGSHINE", "PCMCIA Ethernet Card", 0xf866b0b0, 0x6f6652e0), | ||
1603 | PCMCIA_DEVICE_PROD_ID12("MACNICA", "ME1-JEIDA", 0x20841b68, 0xaf8a3578), | ||
1604 | PCMCIA_DEVICE_PROD_ID12("Macsense", "MPC-10", 0xd830297f, 0xd265c307), | ||
1605 | PCMCIA_DEVICE_PROD_ID12("Matsushita Electric Industrial Co.,LTD.", "CF-VEL211", 0x44445376, 0x8ded41d4), | ||
1606 | PCMCIA_DEVICE_PROD_ID12("MAXTECH", "PCN2000", 0x78d64bc0, 0xca0ca4b8), | ||
1607 | PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC2-T", 0x481e0094, 0xa2eb0cf3), | ||
1608 | PCMCIA_DEVICE_PROD_ID12("MELCO", "LPC2-TX", 0x481e0094, 0x41a6916c), | ||
1609 | PCMCIA_DEVICE_PROD_ID12("Microcom C.E.", "Travel Card LAN 10/100", 0x4b91cec7, 0xe70220d6), | ||
1610 | PCMCIA_DEVICE_PROD_ID12("Microdyne", "NE4200", 0x2e6da59b, 0x0478e472), | ||
1611 | PCMCIA_DEVICE_PROD_ID12("MIDORI ELEC.", "LT-PCMT", 0x648d55c1, 0xbde526c7), | ||
1612 | PCMCIA_DEVICE_PROD_ID12("National Semiconductor", "InfoMover 4100", 0x36e1191f, 0x60c229b9), | ||
1613 | PCMCIA_DEVICE_PROD_ID12("National Semiconductor", "InfoMover NE4100", 0x36e1191f, 0xa6617ec8), | ||
1614 | PCMCIA_DEVICE_PROD_ID12("NEC", "PC-9801N-J12", 0x18df0ba0, 0xbc912d76), | ||
1615 | PCMCIA_DEVICE_PROD_ID12("NETGEAR", "FA410TX", 0x9aa79dc3, 0x60e5bc0e), | ||
1616 | PCMCIA_DEVICE_PROD_ID12("Network Everywhere", "Fast Ethernet 10/100 PC Card", 0x820a67b6, 0x31ed1a5f), | ||
1617 | PCMCIA_DEVICE_PROD_ID12("NextCom K.K.", "Next Hawk", 0xaedaec74, 0xad050ef1), | ||
1618 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100Mbps Ethernet Card", 0x281f1c5d, 0x6e41773b), | ||
1619 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet", 0x281f1c5d, 0x00b2e941), | ||
1620 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "ETHERNET", 0x281f1c5d, 0x3ff7175b), | ||
1621 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet 10BaseT Card", 0x281f1c5d, 0x4de2f6c8), | ||
1622 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet Card", 0x281f1c5d, 0x5e9d92c0), | ||
1623 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Ethernet Combo card", 0x281f1c5d, 0x929c486c), | ||
1624 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "ETHERNET V1.0", 0x281f1c5d, 0x4d8817c8), | ||
1625 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FastEthernet", 0x281f1c5d, 0xfe871eeb), | ||
1626 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "Fast-Ethernet", 0x281f1c5d, 0x45f1f3b4), | ||
1627 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "FAST ETHERNET CARD", 0x281f1c5d, 0xec5dbca7), | ||
1628 | PCMCIA_DEVICE_PROD_ID12("PCMCIA LAN", "Ethernet", 0x7500e246, 0x00b2e941), | ||
1629 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "LNT-10TN", 0x281f1c5d, 0xe707f641), | ||
1630 | PCMCIA_DEVICE_PROD_ID12("PCMCIAs", "ComboCard", 0xdcfe12d3, 0xcd8906cc), | ||
1631 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", "UE2212", 0x281f1c5d, 0xbf17199b), | ||
1632 | PCMCIA_DEVICE_PROD_ID12("PCMCIA", " Ethernet NE2000 Compatible", 0x281f1c5d, 0x42d5d7e1), | ||
1633 | PCMCIA_DEVICE_PROD_ID12("PRETEC", "Ethernet CompactLAN 10baseT 3.3V", 0xebf91155, 0x30074c80), | ||
1634 | PCMCIA_DEVICE_PROD_ID12("PRETEC", "Ethernet CompactLAN 10BaseT 3.3V", 0xebf91155, 0x7f5a4f50), | ||
1635 | PCMCIA_DEVICE_PROD_ID12("Psion Dacom", "Gold Card Ethernet", 0xf5f025c2, 0x3a30e110), | ||
1636 | PCMCIA_DEVICE_PROD_ID12("=RELIA==", "Ethernet", 0xcdd0644a, 0x00b2e941), | ||
1637 | PCMCIA_DEVICE_PROD_ID12("RIOS Systems Co.", "PC CARD3 ETHERNET", 0x7dd33481, 0x10b41826), | ||
1638 | PCMCIA_DEVICE_PROD_ID12("RP", "1625B Ethernet NE2000 Compatible", 0xe3e66e22, 0xb96150df), | ||
1639 | PCMCIA_DEVICE_PROD_ID12("RPTI", "EP400 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4a7e2ae0), | ||
1640 | PCMCIA_DEVICE_PROD_ID12("RPTI", "EP401 Ethernet NE2000 Compatible", 0xdc6f88fd, 0x4bcbd7fd), | ||
1641 | PCMCIA_DEVICE_PROD_ID12("RPTI LTD.", "EP400", 0xc53ac515, 0x81e39388), | ||
1642 | PCMCIA_DEVICE_PROD_ID12("SCM", "Ethernet Combo card", 0xbdc3b102, 0x929c486c), | ||
1643 | PCMCIA_DEVICE_PROD_ID12("Seiko Epson Corp.", "Ethernet", 0x09928730, 0x00b2e941), | ||
1644 | PCMCIA_DEVICE_PROD_ID12("SMC", "EZCard-10-PCMCIA", 0xc4f8b18b, 0xfb21d265), | ||
1645 | PCMCIA_DEVICE_PROD_ID12("Socket Communications Inc", "Socket EA PCMCIA LAN Adapter Revision D", 0xc70a4760, 0x2ade483e), | ||
1646 | PCMCIA_DEVICE_PROD_ID12("Socket Communications Inc", "Socket EA PCMCIA LAN Adapter Revision E", 0xc70a4760, 0x5dd978a8), | ||
1647 | PCMCIA_DEVICE_PROD_ID12("TDK", "LAK-CD031 for PCMCIA", 0x1eae9475, 0x0ed386fa), | ||
1648 | PCMCIA_DEVICE_PROD_ID12("Telecom Device K.K.", "SuperSocket RE450T", 0x466b05f0, 0x8b74bc4f), | ||
1649 | PCMCIA_DEVICE_PROD_ID12("Telecom Device K.K.", "SuperSocket RE550T", 0x466b05f0, 0x33c8db2a), | ||
1650 | PCMCIA_DEVICE_PROD_ID13("Hypertec", "EP401", 0x8787bec7, 0xf6e4a31e), | ||
1651 | PCMCIA_DEVICE_PROD_ID13("KingMax Technology Inc.", "Ethernet Card", 0x932b7189, 0x5e9d92c0), | ||
1652 | PCMCIA_DEVICE_PROD_ID13("LONGSHINE", "EP401", 0xf866b0b0, 0xf6e4a31e), | ||
1653 | PCMCIA_DEVICE_PROD_ID13("Xircom", "CFE-10", 0x2e3ee845, 0x22a49f89), | ||
1654 | PCMCIA_DEVICE_PROD_ID1("CyQ've 10 Base-T LAN CARD", 0x94faf360), | ||
1655 | PCMCIA_DEVICE_PROD_ID1("EP-210 PCMCIA LAN CARD.", 0x8850b4de), | ||
1656 | PCMCIA_DEVICE_PROD_ID1("ETHER-C16", 0x06a8514f), | ||
1657 | PCMCIA_DEVICE_PROD_ID1("NE2000 Compatible", 0x75b8ad5a), | ||
1658 | PCMCIA_DEVICE_PROD_ID2("EN-6200P2", 0xa996d078), | ||
1659 | /* too generic! */ | ||
1660 | /* PCMCIA_DEVICE_PROD_ID12("PCMCIA", "10/100 Ethernet Card", 0x281f1c5d, 0x11b0ffc0), */ | ||
1661 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "cis/PCMLM28.cis"), | ||
1662 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "cis/PCMLM28.cis"), | ||
1663 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"), | ||
1664 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"), | ||
1665 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"), | ||
1666 | PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"), | ||
1667 | PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"), | ||
1668 | PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"), | ||
1669 | PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"), | ||
1670 | PCMCIA_DEVICE_CIS_PROD_ID12("Allied Telesis,K.K", "Ethernet LAN Card", 0x2ad62f3c, 0x9fd2f0a2, "cis/LA-PCM.cis"), | ||
1671 | PCMCIA_DEVICE_CIS_PROD_ID12("KTI", "PE520 PLUS", 0xad180345, 0x9d58d392, "cis/PE520.cis"), | ||
1672 | PCMCIA_DEVICE_CIS_PROD_ID12("NDC", "Ethernet", 0x01c43ae1, 0x00b2e941, "cis/NE2K.cis"), | ||
1673 | PCMCIA_DEVICE_CIS_PROD_ID12("PMX ", "PE-200", 0x34f3f1c8, 0x10b59f8c, "cis/PE-200.cis"), | ||
1674 | PCMCIA_DEVICE_CIS_PROD_ID12("TAMARACK", "Ethernet", 0xcf434fba, 0x00b2e941, "cis/tamarack.cis"), | ||
1675 | PCMCIA_DEVICE_PROD_ID12("Ethernet", "CF Size PC Card", 0x00b2e941, 0x43ac239b), | ||
1676 | PCMCIA_DEVICE_PROD_ID123("Fast Ethernet", "CF Size PC Card", "1.0", | ||
1677 | 0xb4be14e3, 0x43ac239b, 0x0877b627), | ||
1678 | PCMCIA_DEVICE_NULL | ||
1679 | }; | ||
1680 | MODULE_DEVICE_TABLE(pcmcia, pcnet_ids); | ||
1681 | MODULE_FIRMWARE("cis/PCMLM28.cis"); | ||
1682 | MODULE_FIRMWARE("cis/DP83903.cis"); | ||
1683 | MODULE_FIRMWARE("cis/LA-PCM.cis"); | ||
1684 | MODULE_FIRMWARE("cis/PE520.cis"); | ||
1685 | MODULE_FIRMWARE("cis/NE2K.cis"); | ||
1686 | MODULE_FIRMWARE("cis/PE-200.cis"); | ||
1687 | MODULE_FIRMWARE("cis/tamarack.cis"); | ||
1688 | |||
1689 | static struct pcmcia_driver pcnet_driver = { | ||
1690 | .name = "pcnet_cs", | ||
1691 | .probe = pcnet_probe, | ||
1692 | .remove = pcnet_detach, | ||
1693 | .owner = THIS_MODULE, | ||
1694 | .id_table = pcnet_ids, | ||
1695 | .suspend = pcnet_suspend, | ||
1696 | .resume = pcnet_resume, | ||
1697 | }; | ||
1698 | |||
1699 | static int __init init_pcnet_cs(void) | ||
1700 | { | ||
1701 | return pcmcia_register_driver(&pcnet_driver); | ||
1702 | } | ||
1703 | |||
1704 | static void __exit exit_pcnet_cs(void) | ||
1705 | { | ||
1706 | pcmcia_unregister_driver(&pcnet_driver); | ||
1707 | } | ||
1708 | |||
1709 | module_init(init_pcnet_cs); | ||
1710 | module_exit(exit_pcnet_cs); | ||
diff --git a/drivers/net/ethernet/8390/smc-mca.c b/drivers/net/ethernet/8390/smc-mca.c new file mode 100644 index 000000000000..34934fb23b97 --- /dev/null +++ b/drivers/net/ethernet/8390/smc-mca.c | |||
@@ -0,0 +1,576 @@ | |||
1 | /* smc-mca.c: A SMC Ultra ethernet driver for linux. */ | ||
2 | /* | ||
3 | Most of this driver, except for ultramca_probe is nearly | ||
4 | verbatim from smc-ultra.c by Donald Becker. The rest is | ||
5 | written and copyright 1996 by David Weis, weisd3458@uni.edu | ||
6 | |||
7 | This is a driver for the SMC Ultra and SMC EtherEZ ethercards. | ||
8 | |||
9 | This driver uses the cards in the 8390-compatible, shared memory mode. | ||
10 | Most of the run-time complexity is handled by the generic code in | ||
11 | 8390.c. | ||
12 | |||
13 | This driver enables the shared memory only when doing the actual data | ||
14 | transfers to avoid a bug in early version of the card that corrupted | ||
15 | data transferred by a AHA1542. | ||
16 | |||
17 | This driver does not support the programmed-I/O data transfer mode of | ||
18 | the EtherEZ. That support (if available) is smc-ez.c. Nor does it | ||
19 | use the non-8390-compatible "Altego" mode. (No support currently planned.) | ||
20 | |||
21 | Changelog: | ||
22 | |||
23 | Paul Gortmaker : multiple card support for module users. | ||
24 | David Weis : Micro Channel-ized it. | ||
25 | Tom Sightler : Added support for IBM PS/2 Ethernet Adapter/A | ||
26 | Christopher Turcksin : Changed MCA-probe so that multiple adapters are | ||
27 | found correctly (Jul 16, 1997) | ||
28 | Chris Beauregard : Tried to merge the two changes above (Dec 15, 1997) | ||
29 | Tom Sightler : Fixed minor detection bug caused by above merge | ||
30 | Tom Sightler : Added support for three more Western Digital | ||
31 | MCA-adapters | ||
32 | Tom Sightler : Added support for 2.2.x mca_find_unused_adapter | ||
33 | Hartmut Schmidt : - Modified parameter detection to handle each | ||
34 | card differently depending on a switch-list | ||
35 | - 'card_ver' removed from the adapter list | ||
36 | - Some minor bug fixes | ||
37 | */ | ||
38 | |||
39 | #include <linux/mca.h> | ||
40 | #include <linux/module.h> | ||
41 | #include <linux/kernel.h> | ||
42 | #include <linux/errno.h> | ||
43 | #include <linux/string.h> | ||
44 | #include <linux/init.h> | ||
45 | #include <linux/interrupt.h> | ||
46 | #include <linux/netdevice.h> | ||
47 | #include <linux/etherdevice.h> | ||
48 | |||
49 | #include <asm/io.h> | ||
50 | #include <asm/system.h> | ||
51 | |||
52 | #include "8390.h" | ||
53 | |||
54 | #define DRV_NAME "smc-mca" | ||
55 | |||
56 | static int ultramca_open(struct net_device *dev); | ||
57 | static void ultramca_reset_8390(struct net_device *dev); | ||
58 | static void ultramca_get_8390_hdr(struct net_device *dev, | ||
59 | struct e8390_pkt_hdr *hdr, | ||
60 | int ring_page); | ||
61 | static void ultramca_block_input(struct net_device *dev, int count, | ||
62 | struct sk_buff *skb, | ||
63 | int ring_offset); | ||
64 | static void ultramca_block_output(struct net_device *dev, int count, | ||
65 | const unsigned char *buf, | ||
66 | const int start_page); | ||
67 | static int ultramca_close_card(struct net_device *dev); | ||
68 | |||
69 | #define START_PG 0x00 /* First page of TX buffer */ | ||
70 | |||
71 | #define ULTRA_CMDREG 0 /* Offset to ASIC command register. */ | ||
72 | #define ULTRA_RESET 0x80 /* Board reset, in ULTRA_CMDREG. */ | ||
73 | #define ULTRA_MEMENB 0x40 /* Enable the shared memory. */ | ||
74 | #define ULTRA_NIC_OFFSET 16 /* NIC register offset from the base_addr. */ | ||
75 | #define ULTRA_IO_EXTENT 32 | ||
76 | #define EN0_ERWCNT 0x08 /* Early receive warning count. */ | ||
77 | |||
78 | #define _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A 0 | ||
79 | #define _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A 1 | ||
80 | #define _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A 2 | ||
81 | #define _6fc1_WD_Starcard_PLUS_A_WD8003ST_A 3 | ||
82 | #define _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A 4 | ||
83 | #define _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A 5 | ||
84 | #define _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A 6 | ||
85 | #define _efe5_IBM_PS2_Adapter_A_for_Ethernet 7 | ||
86 | |||
87 | struct smc_mca_adapters_t { | ||
88 | unsigned int id; | ||
89 | char *name; | ||
90 | }; | ||
91 | |||
92 | #define MAX_ULTRAMCA_CARDS 4 /* Max number of Ultra cards per module */ | ||
93 | |||
94 | static int ultra_io[MAX_ULTRAMCA_CARDS]; | ||
95 | static int ultra_irq[MAX_ULTRAMCA_CARDS]; | ||
96 | MODULE_LICENSE("GPL"); | ||
97 | |||
98 | module_param_array(ultra_io, int, NULL, 0); | ||
99 | module_param_array(ultra_irq, int, NULL, 0); | ||
100 | MODULE_PARM_DESC(ultra_io, "SMC Ultra/EtherEZ MCA I/O base address(es)"); | ||
101 | MODULE_PARM_DESC(ultra_irq, "SMC Ultra/EtherEZ MCA IRQ number(s)"); | ||
102 | |||
103 | static const struct { | ||
104 | unsigned int base_addr; | ||
105 | } addr_table[] = { | ||
106 | { 0x0800 }, | ||
107 | { 0x1800 }, | ||
108 | { 0x2800 }, | ||
109 | { 0x3800 }, | ||
110 | { 0x4800 }, | ||
111 | { 0x5800 }, | ||
112 | { 0x6800 }, | ||
113 | { 0x7800 }, | ||
114 | { 0x8800 }, | ||
115 | { 0x9800 }, | ||
116 | { 0xa800 }, | ||
117 | { 0xb800 }, | ||
118 | { 0xc800 }, | ||
119 | { 0xd800 }, | ||
120 | { 0xe800 }, | ||
121 | { 0xf800 } | ||
122 | }; | ||
123 | |||
124 | #define MEM_MASK 64 | ||
125 | |||
126 | static const struct { | ||
127 | unsigned char mem_index; | ||
128 | unsigned long mem_start; | ||
129 | unsigned char num_pages; | ||
130 | } mem_table[] = { | ||
131 | { 16, 0x0c0000, 40 }, | ||
132 | { 18, 0x0c4000, 40 }, | ||
133 | { 20, 0x0c8000, 40 }, | ||
134 | { 22, 0x0cc000, 40 }, | ||
135 | { 24, 0x0d0000, 40 }, | ||
136 | { 26, 0x0d4000, 40 }, | ||
137 | { 28, 0x0d8000, 40 }, | ||
138 | { 30, 0x0dc000, 40 }, | ||
139 | {144, 0xfc0000, 40 }, | ||
140 | {148, 0xfc8000, 40 }, | ||
141 | {154, 0xfd0000, 40 }, | ||
142 | {156, 0xfd8000, 40 }, | ||
143 | { 0, 0x0c0000, 20 }, | ||
144 | { 1, 0x0c2000, 20 }, | ||
145 | { 2, 0x0c4000, 20 }, | ||
146 | { 3, 0x0c6000, 20 } | ||
147 | }; | ||
148 | |||
149 | #define IRQ_MASK 243 | ||
150 | static const struct { | ||
151 | unsigned char new_irq; | ||
152 | unsigned char old_irq; | ||
153 | } irq_table[] = { | ||
154 | { 3, 3 }, | ||
155 | { 4, 4 }, | ||
156 | { 10, 10 }, | ||
157 | { 14, 15 } | ||
158 | }; | ||
159 | |||
160 | static short smc_mca_adapter_ids[] __initdata = { | ||
161 | 0x61c8, | ||
162 | 0x61c9, | ||
163 | 0x6fc0, | ||
164 | 0x6fc1, | ||
165 | 0x6fc2, | ||
166 | 0xefd4, | ||
167 | 0xefd5, | ||
168 | 0xefe5, | ||
169 | 0x0000 | ||
170 | }; | ||
171 | |||
172 | static char *smc_mca_adapter_names[] __initdata = { | ||
173 | "SMC Ethercard PLUS Elite/A BNC/AUI (WD8013EP/A)", | ||
174 | "SMC Ethercard PLUS Elite/A UTP/AUI (WD8013WP/A)", | ||
175 | "WD Ethercard PLUS/A (WD8003E/A or WD8003ET/A)", | ||
176 | "WD Starcard PLUS/A (WD8003ST/A)", | ||
177 | "WD Ethercard PLUS 10T/A (WD8003W/A)", | ||
178 | "IBM PS/2 Adapter/A for Ethernet UTP/AUI (WD8013WP/A)", | ||
179 | "IBM PS/2 Adapter/A for Ethernet BNC/AUI (WD8013EP/A)", | ||
180 | "IBM PS/2 Adapter/A for Ethernet", | ||
181 | NULL | ||
182 | }; | ||
183 | |||
184 | static int ultra_found = 0; | ||
185 | |||
186 | |||
187 | static const struct net_device_ops ultramca_netdev_ops = { | ||
188 | .ndo_open = ultramca_open, | ||
189 | .ndo_stop = ultramca_close_card, | ||
190 | |||
191 | .ndo_start_xmit = ei_start_xmit, | ||
192 | .ndo_tx_timeout = ei_tx_timeout, | ||
193 | .ndo_get_stats = ei_get_stats, | ||
194 | .ndo_set_multicast_list = ei_set_multicast_list, | ||
195 | .ndo_validate_addr = eth_validate_addr, | ||
196 | .ndo_set_mac_address = eth_mac_addr, | ||
197 | .ndo_change_mtu = eth_change_mtu, | ||
198 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
199 | .ndo_poll_controller = ei_poll, | ||
200 | #endif | ||
201 | }; | ||
202 | |||
203 | static int __init ultramca_probe(struct device *gen_dev) | ||
204 | { | ||
205 | unsigned short ioaddr; | ||
206 | struct net_device *dev; | ||
207 | unsigned char reg4, num_pages; | ||
208 | struct mca_device *mca_dev = to_mca_device(gen_dev); | ||
209 | char slot = mca_dev->slot; | ||
210 | unsigned char pos2 = 0xff, pos3 = 0xff, pos4 = 0xff, pos5 = 0xff; | ||
211 | int i, rc; | ||
212 | int adapter = mca_dev->index; | ||
213 | int tbase = 0; | ||
214 | int tirq = 0; | ||
215 | int base_addr = ultra_io[ultra_found]; | ||
216 | int irq = ultra_irq[ultra_found]; | ||
217 | |||
218 | if (base_addr || irq) { | ||
219 | printk(KERN_INFO "Probing for SMC MCA adapter"); | ||
220 | if (base_addr) { | ||
221 | printk(KERN_INFO " at I/O address 0x%04x%c", | ||
222 | base_addr, irq ? ' ' : '\n'); | ||
223 | } | ||
224 | if (irq) { | ||
225 | printk(KERN_INFO "using irq %d\n", irq); | ||
226 | } | ||
227 | } | ||
228 | |||
229 | tirq = 0; | ||
230 | tbase = 0; | ||
231 | |||
232 | /* If we're trying to match a specificied irq or io address, | ||
233 | * we'll reject the adapter found unless it's the one we're | ||
234 | * looking for */ | ||
235 | |||
236 | pos2 = mca_device_read_stored_pos(mca_dev, 2); /* io_addr */ | ||
237 | pos3 = mca_device_read_stored_pos(mca_dev, 3); /* shared mem */ | ||
238 | pos4 = mca_device_read_stored_pos(mca_dev, 4); /* ROM bios addr range */ | ||
239 | pos5 = mca_device_read_stored_pos(mca_dev, 5); /* irq, media and RIPL */ | ||
240 | |||
241 | /* Test the following conditions: | ||
242 | * - If an irq parameter is supplied, compare it | ||
243 | * with the irq of the adapter we found | ||
244 | * - If a base_addr paramater is given, compare it | ||
245 | * with the base_addr of the adapter we found | ||
246 | * - Check that the irq and the base_addr of the | ||
247 | * adapter we found is not already in use by | ||
248 | * this driver | ||
249 | */ | ||
250 | |||
251 | switch (mca_dev->index) { | ||
252 | case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A: | ||
253 | case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A: | ||
254 | case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A: | ||
255 | case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A: | ||
256 | { | ||
257 | tbase = addr_table[(pos2 & 0xf0) >> 4].base_addr; | ||
258 | tirq = irq_table[(pos5 & 0xc) >> 2].new_irq; | ||
259 | break; | ||
260 | } | ||
261 | case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A: | ||
262 | case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A: | ||
263 | case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A: | ||
264 | case _efe5_IBM_PS2_Adapter_A_for_Ethernet: | ||
265 | { | ||
266 | tbase = ((pos2 & 0x0fe) * 0x10); | ||
267 | tirq = irq_table[(pos5 & 3)].old_irq; | ||
268 | break; | ||
269 | } | ||
270 | } | ||
271 | |||
272 | if(!tirq || !tbase || | ||
273 | (irq && irq != tirq) || | ||
274 | (base_addr && tbase != base_addr)) | ||
275 | /* FIXME: we're trying to force the ordering of the | ||
276 | * devices here, there should be a way of getting this | ||
277 | * to happen */ | ||
278 | return -ENXIO; | ||
279 | |||
280 | /* Adapter found. */ | ||
281 | dev = alloc_ei_netdev(); | ||
282 | if(!dev) | ||
283 | return -ENODEV; | ||
284 | |||
285 | SET_NETDEV_DEV(dev, gen_dev); | ||
286 | mca_device_set_name(mca_dev, smc_mca_adapter_names[adapter]); | ||
287 | mca_device_set_claim(mca_dev, 1); | ||
288 | |||
289 | printk(KERN_INFO "smc_mca: %s found in slot %d\n", | ||
290 | smc_mca_adapter_names[adapter], slot + 1); | ||
291 | |||
292 | ultra_found++; | ||
293 | |||
294 | dev->base_addr = ioaddr = mca_device_transform_ioport(mca_dev, tbase); | ||
295 | dev->irq = mca_device_transform_irq(mca_dev, tirq); | ||
296 | dev->mem_start = 0; | ||
297 | num_pages = 40; | ||
298 | |||
299 | switch (adapter) { /* card-# in const array above [hs] */ | ||
300 | case _61c8_SMC_Ethercard_PLUS_Elite_A_BNC_AUI_WD8013EP_A: | ||
301 | case _61c9_SMC_Ethercard_PLUS_Elite_A_UTP_AUI_WD8013EP_A: | ||
302 | { | ||
303 | for (i = 0; i < 16; i++) { /* taking 16 counts | ||
304 | * up to 15 [hs] */ | ||
305 | if (mem_table[i].mem_index == (pos3 & ~MEM_MASK)) { | ||
306 | dev->mem_start = (unsigned long) | ||
307 | mca_device_transform_memory(mca_dev, (void *)mem_table[i].mem_start); | ||
308 | num_pages = mem_table[i].num_pages; | ||
309 | } | ||
310 | } | ||
311 | break; | ||
312 | } | ||
313 | case _6fc0_WD_Ethercard_PLUS_A_WD8003E_A_OR_WD8003ET_A: | ||
314 | case _6fc1_WD_Starcard_PLUS_A_WD8003ST_A: | ||
315 | case _6fc2_WD_Ethercard_PLUS_10T_A_WD8003W_A: | ||
316 | case _efe5_IBM_PS2_Adapter_A_for_Ethernet: | ||
317 | { | ||
318 | dev->mem_start = (unsigned long) | ||
319 | mca_device_transform_memory(mca_dev, (void *)((pos3 & 0xfc) * 0x1000)); | ||
320 | num_pages = 0x40; | ||
321 | break; | ||
322 | } | ||
323 | case _efd4_IBM_PS2_Adapter_A_for_Ethernet_UTP_AUI_WD8013WP_A: | ||
324 | case _efd5_IBM_PS2_Adapter_A_for_Ethernet_BNC_AUI_WD8013WP_A: | ||
325 | { | ||
326 | /* courtesy of gamera@quartz.ocn.ne.jp, pos3 indicates | ||
327 | * the index of the 0x2000 step. | ||
328 | * beware different number of pages [hs] | ||
329 | */ | ||
330 | dev->mem_start = (unsigned long) | ||
331 | mca_device_transform_memory(mca_dev, (void *)(0xc0000 + (0x2000 * (pos3 & 0xf)))); | ||
332 | num_pages = 0x20 + (2 * (pos3 & 0x10)); | ||
333 | break; | ||
334 | } | ||
335 | } | ||
336 | |||
337 | /* sanity check, shouldn't happen */ | ||
338 | if (dev->mem_start == 0) { | ||
339 | rc = -ENODEV; | ||
340 | goto err_unclaim; | ||
341 | } | ||
342 | |||
343 | if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) { | ||
344 | rc = -ENODEV; | ||
345 | goto err_unclaim; | ||
346 | } | ||
347 | |||
348 | reg4 = inb(ioaddr + 4) & 0x7f; | ||
349 | outb(reg4, ioaddr + 4); | ||
350 | |||
351 | for (i = 0; i < 6; i++) | ||
352 | dev->dev_addr[i] = inb(ioaddr + 8 + i); | ||
353 | |||
354 | printk(KERN_INFO "smc_mca[%d]: Parameters: %#3x, %pM", | ||
355 | slot + 1, ioaddr, dev->dev_addr); | ||
356 | |||
357 | /* Switch from the station address to the alternate register set | ||
358 | * and read the useful registers there. | ||
359 | */ | ||
360 | |||
361 | outb(0x80 | reg4, ioaddr + 4); | ||
362 | |||
363 | /* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. | ||
364 | */ | ||
365 | |||
366 | outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c); | ||
367 | |||
368 | /* Switch back to the station address register set so that | ||
369 | * the MS-DOS driver can find the card after a warm boot. | ||
370 | */ | ||
371 | |||
372 | outb(reg4, ioaddr + 4); | ||
373 | |||
374 | dev_set_drvdata(gen_dev, dev); | ||
375 | |||
376 | /* The 8390 isn't at the base address, so fake the offset | ||
377 | */ | ||
378 | |||
379 | dev->base_addr = ioaddr + ULTRA_NIC_OFFSET; | ||
380 | |||
381 | ei_status.name = "SMC Ultra MCA"; | ||
382 | ei_status.word16 = 1; | ||
383 | ei_status.tx_start_page = START_PG; | ||
384 | ei_status.rx_start_page = START_PG + TX_PAGES; | ||
385 | ei_status.stop_page = num_pages; | ||
386 | |||
387 | ei_status.mem = ioremap(dev->mem_start, (ei_status.stop_page - START_PG) * 256); | ||
388 | if (!ei_status.mem) { | ||
389 | rc = -ENOMEM; | ||
390 | goto err_release_region; | ||
391 | } | ||
392 | |||
393 | dev->mem_end = dev->mem_start + (ei_status.stop_page - START_PG) * 256; | ||
394 | |||
395 | printk(", IRQ %d memory %#lx-%#lx.\n", | ||
396 | dev->irq, dev->mem_start, dev->mem_end - 1); | ||
397 | |||
398 | ei_status.reset_8390 = &ultramca_reset_8390; | ||
399 | ei_status.block_input = &ultramca_block_input; | ||
400 | ei_status.block_output = &ultramca_block_output; | ||
401 | ei_status.get_8390_hdr = &ultramca_get_8390_hdr; | ||
402 | |||
403 | ei_status.priv = slot; | ||
404 | |||
405 | dev->netdev_ops = &ultramca_netdev_ops; | ||
406 | |||
407 | NS8390_init(dev, 0); | ||
408 | |||
409 | rc = register_netdev(dev); | ||
410 | if (rc) | ||
411 | goto err_unmap; | ||
412 | |||
413 | return 0; | ||
414 | |||
415 | err_unmap: | ||
416 | iounmap(ei_status.mem); | ||
417 | err_release_region: | ||
418 | release_region(ioaddr, ULTRA_IO_EXTENT); | ||
419 | err_unclaim: | ||
420 | mca_device_set_claim(mca_dev, 0); | ||
421 | free_netdev(dev); | ||
422 | return rc; | ||
423 | } | ||
424 | |||
425 | static int ultramca_open(struct net_device *dev) | ||
426 | { | ||
427 | int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ | ||
428 | int retval; | ||
429 | |||
430 | if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) | ||
431 | return retval; | ||
432 | |||
433 | outb(ULTRA_MEMENB, ioaddr); /* Enable memory */ | ||
434 | outb(0x80, ioaddr + 5); /* ??? */ | ||
435 | outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */ | ||
436 | outb(0x04, ioaddr + 5); /* ??? */ | ||
437 | |||
438 | /* Set the early receive warning level in window 0 high enough not | ||
439 | * to receive ERW interrupts. | ||
440 | */ | ||
441 | |||
442 | /* outb_p(E8390_NODMA + E8390_PAGE0, dev->base_addr); | ||
443 | * outb(0xff, dev->base_addr + EN0_ERWCNT); | ||
444 | */ | ||
445 | |||
446 | ei_open(dev); | ||
447 | return 0; | ||
448 | } | ||
449 | |||
450 | static void ultramca_reset_8390(struct net_device *dev) | ||
451 | { | ||
452 | int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ | ||
453 | |||
454 | outb(ULTRA_RESET, ioaddr); | ||
455 | if (ei_debug > 1) | ||
456 | printk("resetting Ultra, t=%ld...", jiffies); | ||
457 | ei_status.txing = 0; | ||
458 | |||
459 | outb(0x80, ioaddr + 5); /* ??? */ | ||
460 | outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */ | ||
461 | |||
462 | if (ei_debug > 1) | ||
463 | printk("reset done\n"); | ||
464 | } | ||
465 | |||
466 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
467 | * we don't need to be concerned with ring wrap as the header will be at | ||
468 | * the start of a page, so we optimize accordingly. | ||
469 | */ | ||
470 | |||
471 | static void ultramca_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
472 | { | ||
473 | void __iomem *hdr_start = ei_status.mem + ((ring_page - START_PG) << 8); | ||
474 | |||
475 | #ifdef notdef | ||
476 | /* Officially this is what we are doing, but the readl() is faster */ | ||
477 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
478 | #else | ||
479 | ((unsigned int*)hdr)[0] = readl(hdr_start); | ||
480 | #endif | ||
481 | } | ||
482 | |||
483 | /* Block input and output are easy on shared memory ethercards, the only | ||
484 | * complication is when the ring buffer wraps. | ||
485 | */ | ||
486 | |||
487 | static void ultramca_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
488 | { | ||
489 | void __iomem *xfer_start = ei_status.mem + ring_offset - START_PG * 256; | ||
490 | |||
491 | if (ring_offset + count > ei_status.stop_page * 256) { | ||
492 | /* We must wrap the input move. */ | ||
493 | int semi_count = ei_status.stop_page * 256 - ring_offset; | ||
494 | memcpy_fromio(skb->data, xfer_start, semi_count); | ||
495 | count -= semi_count; | ||
496 | memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); | ||
497 | } else { | ||
498 | memcpy_fromio(skb->data, xfer_start, count); | ||
499 | } | ||
500 | |||
501 | } | ||
502 | |||
503 | static void ultramca_block_output(struct net_device *dev, int count, const unsigned char *buf, | ||
504 | int start_page) | ||
505 | { | ||
506 | void __iomem *shmem = ei_status.mem + ((start_page - START_PG) << 8); | ||
507 | |||
508 | memcpy_toio(shmem, buf, count); | ||
509 | } | ||
510 | |||
511 | static int ultramca_close_card(struct net_device *dev) | ||
512 | { | ||
513 | int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ | ||
514 | |||
515 | netif_stop_queue(dev); | ||
516 | |||
517 | if (ei_debug > 1) | ||
518 | printk("%s: Shutting down ethercard.\n", dev->name); | ||
519 | |||
520 | outb(0x00, ioaddr + 6); /* Disable interrupts. */ | ||
521 | free_irq(dev->irq, dev); | ||
522 | |||
523 | NS8390_init(dev, 0); | ||
524 | /* We should someday disable shared memory and change to 8-bit mode | ||
525 | * "just in case"... | ||
526 | */ | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | static int ultramca_remove(struct device *gen_dev) | ||
532 | { | ||
533 | struct mca_device *mca_dev = to_mca_device(gen_dev); | ||
534 | struct net_device *dev = dev_get_drvdata(gen_dev); | ||
535 | |||
536 | if (dev) { | ||
537 | /* NB: ultra_close_card() does free_irq */ | ||
538 | int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; | ||
539 | |||
540 | unregister_netdev(dev); | ||
541 | mca_device_set_claim(mca_dev, 0); | ||
542 | release_region(ioaddr, ULTRA_IO_EXTENT); | ||
543 | iounmap(ei_status.mem); | ||
544 | free_netdev(dev); | ||
545 | } | ||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | |||
550 | static struct mca_driver ultra_driver = { | ||
551 | .id_table = smc_mca_adapter_ids, | ||
552 | .driver = { | ||
553 | .name = "smc-mca", | ||
554 | .bus = &mca_bus_type, | ||
555 | .probe = ultramca_probe, | ||
556 | .remove = ultramca_remove, | ||
557 | } | ||
558 | }; | ||
559 | |||
560 | static int __init ultramca_init_module(void) | ||
561 | { | ||
562 | if(!MCA_bus) | ||
563 | return -ENXIO; | ||
564 | |||
565 | mca_register_driver(&ultra_driver); | ||
566 | |||
567 | return ultra_found ? 0 : -ENXIO; | ||
568 | } | ||
569 | |||
570 | static void __exit ultramca_cleanup_module(void) | ||
571 | { | ||
572 | mca_unregister_driver(&ultra_driver); | ||
573 | } | ||
574 | module_init(ultramca_init_module); | ||
575 | module_exit(ultramca_cleanup_module); | ||
576 | |||
diff --git a/drivers/net/ethernet/8390/smc-ultra.c b/drivers/net/ethernet/8390/smc-ultra.c new file mode 100644 index 000000000000..ba44ede29198 --- /dev/null +++ b/drivers/net/ethernet/8390/smc-ultra.c | |||
@@ -0,0 +1,622 @@ | |||
1 | /* smc-ultra.c: A SMC Ultra ethernet driver for linux. */ | ||
2 | /* | ||
3 | This is a driver for the SMC Ultra and SMC EtherEZ ISA ethercards. | ||
4 | |||
5 | Written 1993-1998 by Donald Becker. | ||
6 | |||
7 | Copyright 1993 United States Government as represented by the | ||
8 | Director, National Security Agency. | ||
9 | |||
10 | This software may be used and distributed according to the terms | ||
11 | of the GNU General Public License, incorporated herein by reference. | ||
12 | |||
13 | The author may be reached as becker@scyld.com, or C/O | ||
14 | Scyld Computing Corporation | ||
15 | 410 Severn Ave., Suite 210 | ||
16 | Annapolis MD 21403 | ||
17 | |||
18 | This driver uses the cards in the 8390-compatible mode. | ||
19 | Most of the run-time complexity is handled by the generic code in | ||
20 | 8390.c. The code in this file is responsible for | ||
21 | |||
22 | ultra_probe() Detecting and initializing the card. | ||
23 | ultra_probe1() | ||
24 | ultra_probe_isapnp() | ||
25 | |||
26 | ultra_open() The card-specific details of starting, stopping | ||
27 | ultra_reset_8390() and resetting the 8390 NIC core. | ||
28 | ultra_close() | ||
29 | |||
30 | ultra_block_input() Routines for reading and writing blocks of | ||
31 | ultra_block_output() packet buffer memory. | ||
32 | ultra_pio_input() | ||
33 | ultra_pio_output() | ||
34 | |||
35 | This driver enables the shared memory only when doing the actual data | ||
36 | transfers to avoid a bug in early version of the card that corrupted | ||
37 | data transferred by a AHA1542. | ||
38 | |||
39 | This driver now supports the programmed-I/O (PIO) data transfer mode of | ||
40 | the EtherEZ. It does not use the non-8390-compatible "Altego" mode. | ||
41 | That support (if available) is in smc-ez.c. | ||
42 | |||
43 | Changelog: | ||
44 | |||
45 | Paul Gortmaker : multiple card support for module users. | ||
46 | Donald Becker : 4/17/96 PIO support, minor potential problems avoided. | ||
47 | Donald Becker : 6/6/96 correctly set auto-wrap bit. | ||
48 | Alexander Sotirov : 1/20/01 Added support for ISAPnP cards | ||
49 | |||
50 | Note about the ISA PnP support: | ||
51 | |||
52 | This driver can not autoprobe for more than one SMC EtherEZ PnP card. | ||
53 | You have to configure the second card manually through the /proc/isapnp | ||
54 | interface and then load the module with an explicit io=0x___ option. | ||
55 | */ | ||
56 | |||
57 | static const char version[] = | ||
58 | "smc-ultra.c:v2.02 2/3/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; | ||
59 | |||
60 | #include <linux/module.h> | ||
61 | #include <linux/kernel.h> | ||
62 | #include <linux/errno.h> | ||
63 | #include <linux/string.h> | ||
64 | #include <linux/init.h> | ||
65 | #include <linux/interrupt.h> | ||
66 | #include <linux/isapnp.h> | ||
67 | #include <linux/netdevice.h> | ||
68 | #include <linux/etherdevice.h> | ||
69 | |||
70 | #include <asm/io.h> | ||
71 | #include <asm/irq.h> | ||
72 | #include <asm/system.h> | ||
73 | |||
74 | #include "8390.h" | ||
75 | |||
76 | #define DRV_NAME "smc-ultra" | ||
77 | |||
78 | /* A zero-terminated list of I/O addresses to be probed. */ | ||
79 | static unsigned int ultra_portlist[] __initdata = | ||
80 | {0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380, 0}; | ||
81 | |||
82 | static int ultra_probe1(struct net_device *dev, int ioaddr); | ||
83 | |||
84 | #ifdef __ISAPNP__ | ||
85 | static int ultra_probe_isapnp(struct net_device *dev); | ||
86 | #endif | ||
87 | |||
88 | static int ultra_open(struct net_device *dev); | ||
89 | static void ultra_reset_8390(struct net_device *dev); | ||
90 | static void ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
91 | int ring_page); | ||
92 | static void ultra_block_input(struct net_device *dev, int count, | ||
93 | struct sk_buff *skb, int ring_offset); | ||
94 | static void ultra_block_output(struct net_device *dev, int count, | ||
95 | const unsigned char *buf, const int start_page); | ||
96 | static void ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
97 | int ring_page); | ||
98 | static void ultra_pio_input(struct net_device *dev, int count, | ||
99 | struct sk_buff *skb, int ring_offset); | ||
100 | static void ultra_pio_output(struct net_device *dev, int count, | ||
101 | const unsigned char *buf, const int start_page); | ||
102 | static int ultra_close_card(struct net_device *dev); | ||
103 | |||
104 | #ifdef __ISAPNP__ | ||
105 | static struct isapnp_device_id ultra_device_ids[] __initdata = { | ||
106 | { ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416), | ||
107 | ISAPNP_VENDOR('S','M','C'), ISAPNP_FUNCTION(0x8416), | ||
108 | (long) "SMC EtherEZ (8416)" }, | ||
109 | { } /* terminate list */ | ||
110 | }; | ||
111 | |||
112 | MODULE_DEVICE_TABLE(isapnp, ultra_device_ids); | ||
113 | #endif | ||
114 | |||
115 | |||
116 | #define START_PG 0x00 /* First page of TX buffer */ | ||
117 | |||
118 | #define ULTRA_CMDREG 0 /* Offset to ASIC command register. */ | ||
119 | #define ULTRA_RESET 0x80 /* Board reset, in ULTRA_CMDREG. */ | ||
120 | #define ULTRA_MEMENB 0x40 /* Enable the shared memory. */ | ||
121 | #define IOPD 0x02 /* I/O Pipe Data (16 bits), PIO operation. */ | ||
122 | #define IOPA 0x07 /* I/O Pipe Address for PIO operation. */ | ||
123 | #define ULTRA_NIC_OFFSET 16 /* NIC register offset from the base_addr. */ | ||
124 | #define ULTRA_IO_EXTENT 32 | ||
125 | #define EN0_ERWCNT 0x08 /* Early receive warning count. */ | ||
126 | |||
127 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
128 | static void ultra_poll(struct net_device *dev) | ||
129 | { | ||
130 | disable_irq(dev->irq); | ||
131 | ei_interrupt(dev->irq, dev); | ||
132 | enable_irq(dev->irq); | ||
133 | } | ||
134 | #endif | ||
135 | /* Probe for the Ultra. This looks like a 8013 with the station | ||
136 | address PROM at I/O ports <base>+8 to <base>+13, with a checksum | ||
137 | following. | ||
138 | */ | ||
139 | |||
140 | static int __init do_ultra_probe(struct net_device *dev) | ||
141 | { | ||
142 | int i; | ||
143 | int base_addr = dev->base_addr; | ||
144 | int irq = dev->irq; | ||
145 | |||
146 | if (base_addr > 0x1ff) /* Check a single specified location. */ | ||
147 | return ultra_probe1(dev, base_addr); | ||
148 | else if (base_addr != 0) /* Don't probe at all. */ | ||
149 | return -ENXIO; | ||
150 | |||
151 | #ifdef __ISAPNP__ | ||
152 | /* Look for any installed ISAPnP cards */ | ||
153 | if (isapnp_present() && (ultra_probe_isapnp(dev) == 0)) | ||
154 | return 0; | ||
155 | #endif | ||
156 | |||
157 | for (i = 0; ultra_portlist[i]; i++) { | ||
158 | dev->irq = irq; | ||
159 | if (ultra_probe1(dev, ultra_portlist[i]) == 0) | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | return -ENODEV; | ||
164 | } | ||
165 | |||
166 | #ifndef MODULE | ||
167 | struct net_device * __init ultra_probe(int unit) | ||
168 | { | ||
169 | struct net_device *dev = alloc_ei_netdev(); | ||
170 | int err; | ||
171 | |||
172 | if (!dev) | ||
173 | return ERR_PTR(-ENOMEM); | ||
174 | |||
175 | sprintf(dev->name, "eth%d", unit); | ||
176 | netdev_boot_setup_check(dev); | ||
177 | |||
178 | err = do_ultra_probe(dev); | ||
179 | if (err) | ||
180 | goto out; | ||
181 | return dev; | ||
182 | out: | ||
183 | free_netdev(dev); | ||
184 | return ERR_PTR(err); | ||
185 | } | ||
186 | #endif | ||
187 | |||
188 | static const struct net_device_ops ultra_netdev_ops = { | ||
189 | .ndo_open = ultra_open, | ||
190 | .ndo_stop = ultra_close_card, | ||
191 | |||
192 | .ndo_start_xmit = ei_start_xmit, | ||
193 | .ndo_tx_timeout = ei_tx_timeout, | ||
194 | .ndo_get_stats = ei_get_stats, | ||
195 | .ndo_set_multicast_list = ei_set_multicast_list, | ||
196 | .ndo_validate_addr = eth_validate_addr, | ||
197 | .ndo_set_mac_address = eth_mac_addr, | ||
198 | .ndo_change_mtu = eth_change_mtu, | ||
199 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
200 | .ndo_poll_controller = ultra_poll, | ||
201 | #endif | ||
202 | }; | ||
203 | |||
204 | static int __init ultra_probe1(struct net_device *dev, int ioaddr) | ||
205 | { | ||
206 | int i, retval; | ||
207 | int checksum = 0; | ||
208 | const char *model_name; | ||
209 | unsigned char eeprom_irq = 0; | ||
210 | static unsigned version_printed; | ||
211 | /* Values from various config regs. */ | ||
212 | unsigned char num_pages, irqreg, addr, piomode; | ||
213 | unsigned char idreg = inb(ioaddr + 7); | ||
214 | unsigned char reg4 = inb(ioaddr + 4) & 0x7f; | ||
215 | |||
216 | if (!request_region(ioaddr, ULTRA_IO_EXTENT, DRV_NAME)) | ||
217 | return -EBUSY; | ||
218 | |||
219 | /* Check the ID nibble. */ | ||
220 | if ((idreg & 0xF0) != 0x20 /* SMC Ultra */ | ||
221 | && (idreg & 0xF0) != 0x40) { /* SMC EtherEZ */ | ||
222 | retval = -ENODEV; | ||
223 | goto out; | ||
224 | } | ||
225 | |||
226 | /* Select the station address register set. */ | ||
227 | outb(reg4, ioaddr + 4); | ||
228 | |||
229 | for (i = 0; i < 8; i++) | ||
230 | checksum += inb(ioaddr + 8 + i); | ||
231 | if ((checksum & 0xff) != 0xFF) { | ||
232 | retval = -ENODEV; | ||
233 | goto out; | ||
234 | } | ||
235 | |||
236 | if (ei_debug && version_printed++ == 0) | ||
237 | printk(version); | ||
238 | |||
239 | model_name = (idreg & 0xF0) == 0x20 ? "SMC Ultra" : "SMC EtherEZ"; | ||
240 | |||
241 | for (i = 0; i < 6; i++) | ||
242 | dev->dev_addr[i] = inb(ioaddr + 8 + i); | ||
243 | |||
244 | printk("%s: %s at %#3x, %pM", dev->name, model_name, | ||
245 | ioaddr, dev->dev_addr); | ||
246 | |||
247 | /* Switch from the station address to the alternate register set and | ||
248 | read the useful registers there. */ | ||
249 | outb(0x80 | reg4, ioaddr + 4); | ||
250 | |||
251 | /* Enabled FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */ | ||
252 | outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c); | ||
253 | piomode = inb(ioaddr + 0x8); | ||
254 | addr = inb(ioaddr + 0xb); | ||
255 | irqreg = inb(ioaddr + 0xd); | ||
256 | |||
257 | /* Switch back to the station address register set so that the MS-DOS driver | ||
258 | can find the card after a warm boot. */ | ||
259 | outb(reg4, ioaddr + 4); | ||
260 | |||
261 | if (dev->irq < 2) { | ||
262 | unsigned char irqmap[] = {0, 9, 3, 5, 7, 10, 11, 15}; | ||
263 | int irq; | ||
264 | |||
265 | /* The IRQ bits are split. */ | ||
266 | irq = irqmap[((irqreg & 0x40) >> 4) + ((irqreg & 0x0c) >> 2)]; | ||
267 | |||
268 | if (irq == 0) { | ||
269 | printk(", failed to detect IRQ line.\n"); | ||
270 | retval = -EAGAIN; | ||
271 | goto out; | ||
272 | } | ||
273 | dev->irq = irq; | ||
274 | eeprom_irq = 1; | ||
275 | } | ||
276 | |||
277 | /* The 8390 isn't at the base address, so fake the offset */ | ||
278 | dev->base_addr = ioaddr+ULTRA_NIC_OFFSET; | ||
279 | |||
280 | { | ||
281 | static const int addr_tbl[4] = { | ||
282 | 0x0C0000, 0x0E0000, 0xFC0000, 0xFE0000 | ||
283 | }; | ||
284 | static const short num_pages_tbl[4] = { | ||
285 | 0x20, 0x40, 0x80, 0xff | ||
286 | }; | ||
287 | |||
288 | dev->mem_start = ((addr & 0x0f) << 13) + addr_tbl[(addr >> 6) & 3] ; | ||
289 | num_pages = num_pages_tbl[(addr >> 4) & 3]; | ||
290 | } | ||
291 | |||
292 | ei_status.name = model_name; | ||
293 | ei_status.word16 = 1; | ||
294 | ei_status.tx_start_page = START_PG; | ||
295 | ei_status.rx_start_page = START_PG + TX_PAGES; | ||
296 | ei_status.stop_page = num_pages; | ||
297 | |||
298 | ei_status.mem = ioremap(dev->mem_start, (ei_status.stop_page - START_PG)*256); | ||
299 | if (!ei_status.mem) { | ||
300 | printk(", failed to ioremap.\n"); | ||
301 | retval = -ENOMEM; | ||
302 | goto out; | ||
303 | } | ||
304 | |||
305 | dev->mem_end = dev->mem_start + (ei_status.stop_page - START_PG)*256; | ||
306 | |||
307 | if (piomode) { | ||
308 | printk(",%s IRQ %d programmed-I/O mode.\n", | ||
309 | eeprom_irq ? "EEPROM" : "assigned ", dev->irq); | ||
310 | ei_status.block_input = &ultra_pio_input; | ||
311 | ei_status.block_output = &ultra_pio_output; | ||
312 | ei_status.get_8390_hdr = &ultra_pio_get_hdr; | ||
313 | } else { | ||
314 | printk(",%s IRQ %d memory %#lx-%#lx.\n", eeprom_irq ? "" : "assigned ", | ||
315 | dev->irq, dev->mem_start, dev->mem_end-1); | ||
316 | ei_status.block_input = &ultra_block_input; | ||
317 | ei_status.block_output = &ultra_block_output; | ||
318 | ei_status.get_8390_hdr = &ultra_get_8390_hdr; | ||
319 | } | ||
320 | ei_status.reset_8390 = &ultra_reset_8390; | ||
321 | |||
322 | dev->netdev_ops = &ultra_netdev_ops; | ||
323 | NS8390_init(dev, 0); | ||
324 | |||
325 | retval = register_netdev(dev); | ||
326 | if (retval) | ||
327 | goto out; | ||
328 | return 0; | ||
329 | out: | ||
330 | release_region(ioaddr, ULTRA_IO_EXTENT); | ||
331 | return retval; | ||
332 | } | ||
333 | |||
334 | #ifdef __ISAPNP__ | ||
335 | static int __init ultra_probe_isapnp(struct net_device *dev) | ||
336 | { | ||
337 | int i; | ||
338 | |||
339 | for (i = 0; ultra_device_ids[i].vendor != 0; i++) { | ||
340 | struct pnp_dev *idev = NULL; | ||
341 | |||
342 | while ((idev = pnp_find_dev(NULL, | ||
343 | ultra_device_ids[i].vendor, | ||
344 | ultra_device_ids[i].function, | ||
345 | idev))) { | ||
346 | /* Avoid already found cards from previous calls */ | ||
347 | if (pnp_device_attach(idev) < 0) | ||
348 | continue; | ||
349 | if (pnp_activate_dev(idev) < 0) { | ||
350 | __again: | ||
351 | pnp_device_detach(idev); | ||
352 | continue; | ||
353 | } | ||
354 | /* if no io and irq, search for next */ | ||
355 | if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) | ||
356 | goto __again; | ||
357 | /* found it */ | ||
358 | dev->base_addr = pnp_port_start(idev, 0); | ||
359 | dev->irq = pnp_irq(idev, 0); | ||
360 | printk(KERN_INFO "smc-ultra.c: ISAPnP reports %s at i/o %#lx, irq %d.\n", | ||
361 | (char *) ultra_device_ids[i].driver_data, | ||
362 | dev->base_addr, dev->irq); | ||
363 | if (ultra_probe1(dev, dev->base_addr) != 0) { /* Shouldn't happen. */ | ||
364 | printk(KERN_ERR "smc-ultra.c: Probe of ISAPnP card at %#lx failed.\n", dev->base_addr); | ||
365 | pnp_device_detach(idev); | ||
366 | return -ENXIO; | ||
367 | } | ||
368 | ei_status.priv = (unsigned long)idev; | ||
369 | break; | ||
370 | } | ||
371 | if (!idev) | ||
372 | continue; | ||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | return -ENODEV; | ||
377 | } | ||
378 | #endif | ||
379 | |||
380 | static int | ||
381 | ultra_open(struct net_device *dev) | ||
382 | { | ||
383 | int retval; | ||
384 | int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ | ||
385 | unsigned char irq2reg[] = {0, 0, 0x04, 0x08, 0, 0x0C, 0, 0x40, | ||
386 | 0, 0x04, 0x44, 0x48, 0, 0, 0, 0x4C, }; | ||
387 | |||
388 | retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev); | ||
389 | if (retval) | ||
390 | return retval; | ||
391 | |||
392 | outb(0x00, ioaddr); /* Disable shared memory for safety. */ | ||
393 | outb(0x80, ioaddr + 5); | ||
394 | /* Set the IRQ line. */ | ||
395 | outb(inb(ioaddr + 4) | 0x80, ioaddr + 4); | ||
396 | outb((inb(ioaddr + 13) & ~0x4C) | irq2reg[dev->irq], ioaddr + 13); | ||
397 | outb(inb(ioaddr + 4) & 0x7f, ioaddr + 4); | ||
398 | |||
399 | if (ei_status.block_input == &ultra_pio_input) { | ||
400 | outb(0x11, ioaddr + 6); /* Enable interrupts and PIO. */ | ||
401 | outb(0x01, ioaddr + 0x19); /* Enable ring read auto-wrap. */ | ||
402 | } else | ||
403 | outb(0x01, ioaddr + 6); /* Enable interrupts and memory. */ | ||
404 | /* Set the early receive warning level in window 0 high enough not | ||
405 | to receive ERW interrupts. */ | ||
406 | outb_p(E8390_NODMA+E8390_PAGE0, dev->base_addr); | ||
407 | outb(0xff, dev->base_addr + EN0_ERWCNT); | ||
408 | ei_open(dev); | ||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | static void | ||
413 | ultra_reset_8390(struct net_device *dev) | ||
414 | { | ||
415 | int cmd_port = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC base addr */ | ||
416 | |||
417 | outb(ULTRA_RESET, cmd_port); | ||
418 | if (ei_debug > 1) printk("resetting Ultra, t=%ld...", jiffies); | ||
419 | ei_status.txing = 0; | ||
420 | |||
421 | outb(0x00, cmd_port); /* Disable shared memory for safety. */ | ||
422 | outb(0x80, cmd_port + 5); | ||
423 | if (ei_status.block_input == &ultra_pio_input) | ||
424 | outb(0x11, cmd_port + 6); /* Enable interrupts and PIO. */ | ||
425 | else | ||
426 | outb(0x01, cmd_port + 6); /* Enable interrupts and memory. */ | ||
427 | |||
428 | if (ei_debug > 1) printk("reset done\n"); | ||
429 | } | ||
430 | |||
431 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
432 | we don't need to be concerned with ring wrap as the header will be at | ||
433 | the start of a page, so we optimize accordingly. */ | ||
434 | |||
435 | static void | ||
436 | ultra_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
437 | { | ||
438 | void __iomem *hdr_start = ei_status.mem + ((ring_page - START_PG)<<8); | ||
439 | |||
440 | outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem on */ | ||
441 | #ifdef __BIG_ENDIAN | ||
442 | /* Officially this is what we are doing, but the readl() is faster */ | ||
443 | /* unfortunately it isn't endian aware of the struct */ | ||
444 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
445 | hdr->count = le16_to_cpu(hdr->count); | ||
446 | #else | ||
447 | ((unsigned int*)hdr)[0] = readl(hdr_start); | ||
448 | #endif | ||
449 | outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* shmem off */ | ||
450 | } | ||
451 | |||
452 | /* Block input and output are easy on shared memory ethercards, the only | ||
453 | complication is when the ring buffer wraps. */ | ||
454 | |||
455 | static void | ||
456 | ultra_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
457 | { | ||
458 | void __iomem *xfer_start = ei_status.mem + ring_offset - (START_PG<<8); | ||
459 | |||
460 | /* Enable shared memory. */ | ||
461 | outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); | ||
462 | |||
463 | if (ring_offset + count > ei_status.stop_page*256) { | ||
464 | /* We must wrap the input move. */ | ||
465 | int semi_count = ei_status.stop_page*256 - ring_offset; | ||
466 | memcpy_fromio(skb->data, xfer_start, semi_count); | ||
467 | count -= semi_count; | ||
468 | memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); | ||
469 | } else { | ||
470 | memcpy_fromio(skb->data, xfer_start, count); | ||
471 | } | ||
472 | |||
473 | outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */ | ||
474 | } | ||
475 | |||
476 | static void | ||
477 | ultra_block_output(struct net_device *dev, int count, const unsigned char *buf, | ||
478 | int start_page) | ||
479 | { | ||
480 | void __iomem *shmem = ei_status.mem + ((start_page - START_PG)<<8); | ||
481 | |||
482 | /* Enable shared memory. */ | ||
483 | outb(ULTRA_MEMENB, dev->base_addr - ULTRA_NIC_OFFSET); | ||
484 | |||
485 | memcpy_toio(shmem, buf, count); | ||
486 | |||
487 | outb(0x00, dev->base_addr - ULTRA_NIC_OFFSET); /* Disable memory. */ | ||
488 | } | ||
489 | |||
490 | /* The identical operations for programmed I/O cards. | ||
491 | The PIO model is trivial to use: the 16 bit start address is written | ||
492 | byte-sequentially to IOPA, with no intervening I/O operations, and the | ||
493 | data is read or written to the IOPD data port. | ||
494 | The only potential complication is that the address register is shared | ||
495 | and must be always be rewritten between each read/write direction change. | ||
496 | This is no problem for us, as the 8390 code ensures that we are single | ||
497 | threaded. */ | ||
498 | static void ultra_pio_get_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
499 | int ring_page) | ||
500 | { | ||
501 | int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ | ||
502 | outb(0x00, ioaddr + IOPA); /* Set the address, LSB first. */ | ||
503 | outb(ring_page, ioaddr + IOPA); | ||
504 | insw(ioaddr + IOPD, hdr, sizeof(struct e8390_pkt_hdr)>>1); | ||
505 | } | ||
506 | |||
507 | static void ultra_pio_input(struct net_device *dev, int count, | ||
508 | struct sk_buff *skb, int ring_offset) | ||
509 | { | ||
510 | int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ | ||
511 | char *buf = skb->data; | ||
512 | |||
513 | /* For now set the address again, although it should already be correct. */ | ||
514 | outb(ring_offset, ioaddr + IOPA); /* Set the address, LSB first. */ | ||
515 | outb(ring_offset >> 8, ioaddr + IOPA); | ||
516 | /* We know skbuffs are padded to at least word alignment. */ | ||
517 | insw(ioaddr + IOPD, buf, (count+1)>>1); | ||
518 | } | ||
519 | |||
520 | static void ultra_pio_output(struct net_device *dev, int count, | ||
521 | const unsigned char *buf, const int start_page) | ||
522 | { | ||
523 | int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* ASIC addr */ | ||
524 | outb(0x00, ioaddr + IOPA); /* Set the address, LSB first. */ | ||
525 | outb(start_page, ioaddr + IOPA); | ||
526 | /* An extra odd byte is OK here as well. */ | ||
527 | outsw(ioaddr + IOPD, buf, (count+1)>>1); | ||
528 | } | ||
529 | |||
530 | static int | ||
531 | ultra_close_card(struct net_device *dev) | ||
532 | { | ||
533 | int ioaddr = dev->base_addr - ULTRA_NIC_OFFSET; /* CMDREG */ | ||
534 | |||
535 | netif_stop_queue(dev); | ||
536 | |||
537 | if (ei_debug > 1) | ||
538 | printk("%s: Shutting down ethercard.\n", dev->name); | ||
539 | |||
540 | outb(0x00, ioaddr + 6); /* Disable interrupts. */ | ||
541 | free_irq(dev->irq, dev); | ||
542 | |||
543 | NS8390_init(dev, 0); | ||
544 | |||
545 | /* We should someday disable shared memory and change to 8-bit mode | ||
546 | "just in case"... */ | ||
547 | |||
548 | return 0; | ||
549 | } | ||
550 | |||
551 | |||
552 | #ifdef MODULE | ||
553 | #define MAX_ULTRA_CARDS 4 /* Max number of Ultra cards per module */ | ||
554 | static struct net_device *dev_ultra[MAX_ULTRA_CARDS]; | ||
555 | static int io[MAX_ULTRA_CARDS]; | ||
556 | static int irq[MAX_ULTRA_CARDS]; | ||
557 | |||
558 | module_param_array(io, int, NULL, 0); | ||
559 | module_param_array(irq, int, NULL, 0); | ||
560 | MODULE_PARM_DESC(io, "I/O base address(es)"); | ||
561 | MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)"); | ||
562 | MODULE_DESCRIPTION("SMC Ultra/EtherEZ ISA/PnP Ethernet driver"); | ||
563 | MODULE_LICENSE("GPL"); | ||
564 | |||
565 | /* This is set up so that only a single autoprobe takes place per call. | ||
566 | ISA device autoprobes on a running machine are not recommended. */ | ||
567 | int __init | ||
568 | init_module(void) | ||
569 | { | ||
570 | struct net_device *dev; | ||
571 | int this_dev, found = 0; | ||
572 | |||
573 | for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { | ||
574 | if (io[this_dev] == 0) { | ||
575 | if (this_dev != 0) break; /* only autoprobe 1st one */ | ||
576 | printk(KERN_NOTICE "smc-ultra.c: Presently autoprobing (not recommended) for a single card.\n"); | ||
577 | } | ||
578 | dev = alloc_ei_netdev(); | ||
579 | if (!dev) | ||
580 | break; | ||
581 | dev->irq = irq[this_dev]; | ||
582 | dev->base_addr = io[this_dev]; | ||
583 | if (do_ultra_probe(dev) == 0) { | ||
584 | dev_ultra[found++] = dev; | ||
585 | continue; | ||
586 | } | ||
587 | free_netdev(dev); | ||
588 | printk(KERN_WARNING "smc-ultra.c: No SMC Ultra card found (i/o = 0x%x).\n", io[this_dev]); | ||
589 | break; | ||
590 | } | ||
591 | if (found) | ||
592 | return 0; | ||
593 | return -ENXIO; | ||
594 | } | ||
595 | |||
596 | static void cleanup_card(struct net_device *dev) | ||
597 | { | ||
598 | /* NB: ultra_close_card() does free_irq */ | ||
599 | #ifdef __ISAPNP__ | ||
600 | struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; | ||
601 | if (idev) | ||
602 | pnp_device_detach(idev); | ||
603 | #endif | ||
604 | release_region(dev->base_addr - ULTRA_NIC_OFFSET, ULTRA_IO_EXTENT); | ||
605 | iounmap(ei_status.mem); | ||
606 | } | ||
607 | |||
608 | void __exit | ||
609 | cleanup_module(void) | ||
610 | { | ||
611 | int this_dev; | ||
612 | |||
613 | for (this_dev = 0; this_dev < MAX_ULTRA_CARDS; this_dev++) { | ||
614 | struct net_device *dev = dev_ultra[this_dev]; | ||
615 | if (dev) { | ||
616 | unregister_netdev(dev); | ||
617 | cleanup_card(dev); | ||
618 | free_netdev(dev); | ||
619 | } | ||
620 | } | ||
621 | } | ||
622 | #endif /* MODULE */ | ||
diff --git a/drivers/net/ethernet/8390/smc-ultra32.c b/drivers/net/ethernet/8390/smc-ultra32.c new file mode 100644 index 000000000000..e459c3b2510a --- /dev/null +++ b/drivers/net/ethernet/8390/smc-ultra32.c | |||
@@ -0,0 +1,464 @@ | |||
1 | /* smc-ultra32.c: An SMC Ultra32 EISA ethernet driver for linux. | ||
2 | |||
3 | Sources: | ||
4 | |||
5 | This driver is based on (cloned from) the ISA SMC Ultra driver | ||
6 | written by Donald Becker. Modifications to support the EISA | ||
7 | version of the card by Paul Gortmaker and Leonard N. Zubkoff. | ||
8 | |||
9 | This software may be used and distributed according to the terms | ||
10 | of the GNU General Public License, incorporated herein by reference. | ||
11 | |||
12 | Theory of Operation: | ||
13 | |||
14 | The SMC Ultra32C card uses the SMC 83c790 chip which is also | ||
15 | found on the ISA SMC Ultra cards. It has a shared memory mode of | ||
16 | operation that makes it similar to the ISA version of the card. | ||
17 | The main difference is that the EISA card has 32KB of RAM, but | ||
18 | only an 8KB window into that memory. The EISA card also can be | ||
19 | set for a bus-mastering mode of operation via the ECU, but that | ||
20 | is not (and probably will never be) supported by this driver. | ||
21 | The ECU should be run to enable shared memory and to disable the | ||
22 | bus-mastering feature for use with linux. | ||
23 | |||
24 | By programming the 8390 to use only 8KB RAM, the modifications | ||
25 | to the ISA driver can be limited to the probe and initialization | ||
26 | code. This allows easy integration of EISA support into the ISA | ||
27 | driver. However, the driver development kit from SMC provided the | ||
28 | register information for sliding the 8KB window, and hence the 8390 | ||
29 | is programmed to use the full 32KB RAM. | ||
30 | |||
31 | Unfortunately this required code changes outside the probe/init | ||
32 | routines, and thus we decided to separate the EISA driver from | ||
33 | the ISA one. In this way, ISA users don't end up with a larger | ||
34 | driver due to the EISA code, and EISA users don't end up with a | ||
35 | larger driver due to the ISA EtherEZ PIO code. The driver is | ||
36 | similar to the 3c503/16 driver, in that the window must be set | ||
37 | back to the 1st 8KB of space for access to the two 8390 Tx slots. | ||
38 | |||
39 | In testing, using only 8KB RAM (3 Tx / 5 Rx) didn't appear to | ||
40 | be a limiting factor, since the EISA bus could get packets off | ||
41 | the card fast enough, but having the use of lots of RAM as Rx | ||
42 | space is extra insurance if interrupt latencies become excessive. | ||
43 | |||
44 | */ | ||
45 | |||
46 | static const char *version = "smc-ultra32.c: 06/97 v1.00\n"; | ||
47 | |||
48 | |||
49 | #include <linux/module.h> | ||
50 | #include <linux/eisa.h> | ||
51 | #include <linux/kernel.h> | ||
52 | #include <linux/errno.h> | ||
53 | #include <linux/string.h> | ||
54 | #include <linux/init.h> | ||
55 | #include <linux/interrupt.h> | ||
56 | #include <linux/netdevice.h> | ||
57 | #include <linux/etherdevice.h> | ||
58 | |||
59 | #include <asm/io.h> | ||
60 | #include <asm/system.h> | ||
61 | |||
62 | #include "8390.h" | ||
63 | |||
64 | #define DRV_NAME "smc-ultra32" | ||
65 | |||
66 | static int ultra32_probe1(struct net_device *dev, int ioaddr); | ||
67 | static int ultra32_open(struct net_device *dev); | ||
68 | static void ultra32_reset_8390(struct net_device *dev); | ||
69 | static void ultra32_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
70 | int ring_page); | ||
71 | static void ultra32_block_input(struct net_device *dev, int count, | ||
72 | struct sk_buff *skb, int ring_offset); | ||
73 | static void ultra32_block_output(struct net_device *dev, int count, | ||
74 | const unsigned char *buf, | ||
75 | const int start_page); | ||
76 | static int ultra32_close(struct net_device *dev); | ||
77 | |||
78 | #define ULTRA32_CMDREG 0 /* Offset to ASIC command register. */ | ||
79 | #define ULTRA32_RESET 0x80 /* Board reset, in ULTRA32_CMDREG. */ | ||
80 | #define ULTRA32_MEMENB 0x40 /* Enable the shared memory. */ | ||
81 | #define ULTRA32_NIC_OFFSET 16 /* NIC register offset from the base_addr. */ | ||
82 | #define ULTRA32_IO_EXTENT 32 | ||
83 | #define EN0_ERWCNT 0x08 /* Early receive warning count. */ | ||
84 | |||
85 | /* | ||
86 | * Defines that apply only to the Ultra32 EISA card. Note that | ||
87 | * "smc" = 10011 01101 00011 = 0x4da3, and hence !smc8010.cfg translates | ||
88 | * into an EISA ID of 0x1080A34D | ||
89 | */ | ||
90 | #define ULTRA32_BASE 0xca0 | ||
91 | #define ULTRA32_ID 0x1080a34d | ||
92 | #define ULTRA32_IDPORT (-0x20) /* 0xc80 */ | ||
93 | /* Config regs 1->7 from the EISA !SMC8010.CFG file. */ | ||
94 | #define ULTRA32_CFG1 0x04 /* 0xca4 */ | ||
95 | #define ULTRA32_CFG2 0x05 /* 0xca5 */ | ||
96 | #define ULTRA32_CFG3 (-0x18) /* 0xc88 */ | ||
97 | #define ULTRA32_CFG4 (-0x17) /* 0xc89 */ | ||
98 | #define ULTRA32_CFG5 (-0x16) /* 0xc8a */ | ||
99 | #define ULTRA32_CFG6 (-0x15) /* 0xc8b */ | ||
100 | #define ULTRA32_CFG7 0x0d /* 0xcad */ | ||
101 | |||
102 | static void cleanup_card(struct net_device *dev) | ||
103 | { | ||
104 | int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; | ||
105 | /* NB: ultra32_close_card() does free_irq */ | ||
106 | release_region(ioaddr, ULTRA32_IO_EXTENT); | ||
107 | iounmap(ei_status.mem); | ||
108 | } | ||
109 | |||
110 | /* Probe for the Ultra32. This looks like a 8013 with the station | ||
111 | address PROM at I/O ports <base>+8 to <base>+13, with a checksum | ||
112 | following. | ||
113 | */ | ||
114 | |||
115 | struct net_device * __init ultra32_probe(int unit) | ||
116 | { | ||
117 | struct net_device *dev; | ||
118 | int base; | ||
119 | int irq; | ||
120 | int err = -ENODEV; | ||
121 | |||
122 | if (!EISA_bus) | ||
123 | return ERR_PTR(-ENODEV); | ||
124 | |||
125 | dev = alloc_ei_netdev(); | ||
126 | |||
127 | if (!dev) | ||
128 | return ERR_PTR(-ENOMEM); | ||
129 | |||
130 | if (unit >= 0) { | ||
131 | sprintf(dev->name, "eth%d", unit); | ||
132 | netdev_boot_setup_check(dev); | ||
133 | } | ||
134 | |||
135 | irq = dev->irq; | ||
136 | |||
137 | /* EISA spec allows for up to 16 slots, but 8 is typical. */ | ||
138 | for (base = 0x1000 + ULTRA32_BASE; base < 0x9000; base += 0x1000) { | ||
139 | if (ultra32_probe1(dev, base) == 0) | ||
140 | break; | ||
141 | dev->irq = irq; | ||
142 | } | ||
143 | if (base >= 0x9000) | ||
144 | goto out; | ||
145 | err = register_netdev(dev); | ||
146 | if (err) | ||
147 | goto out1; | ||
148 | return dev; | ||
149 | out1: | ||
150 | cleanup_card(dev); | ||
151 | out: | ||
152 | free_netdev(dev); | ||
153 | return ERR_PTR(err); | ||
154 | } | ||
155 | |||
156 | |||
157 | static const struct net_device_ops ultra32_netdev_ops = { | ||
158 | .ndo_open = ultra32_open, | ||
159 | .ndo_stop = ultra32_close, | ||
160 | .ndo_start_xmit = ei_start_xmit, | ||
161 | .ndo_tx_timeout = ei_tx_timeout, | ||
162 | .ndo_get_stats = ei_get_stats, | ||
163 | .ndo_set_multicast_list = ei_set_multicast_list, | ||
164 | .ndo_validate_addr = eth_validate_addr, | ||
165 | .ndo_set_mac_address = eth_mac_addr, | ||
166 | .ndo_change_mtu = eth_change_mtu, | ||
167 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
168 | .ndo_poll_controller = ei_poll, | ||
169 | #endif | ||
170 | }; | ||
171 | |||
172 | static int __init ultra32_probe1(struct net_device *dev, int ioaddr) | ||
173 | { | ||
174 | int i, edge, media, retval; | ||
175 | int checksum = 0; | ||
176 | const char *model_name; | ||
177 | static unsigned version_printed; | ||
178 | /* Values from various config regs. */ | ||
179 | unsigned char idreg; | ||
180 | unsigned char reg4; | ||
181 | const char *ifmap[] = {"UTP No Link", "", "UTP/AUI", "UTP/BNC"}; | ||
182 | |||
183 | if (!request_region(ioaddr, ULTRA32_IO_EXTENT, DRV_NAME)) | ||
184 | return -EBUSY; | ||
185 | |||
186 | if (inb(ioaddr + ULTRA32_IDPORT) == 0xff || | ||
187 | inl(ioaddr + ULTRA32_IDPORT) != ULTRA32_ID) { | ||
188 | retval = -ENODEV; | ||
189 | goto out; | ||
190 | } | ||
191 | |||
192 | media = inb(ioaddr + ULTRA32_CFG7) & 0x03; | ||
193 | edge = inb(ioaddr + ULTRA32_CFG5) & 0x08; | ||
194 | printk("SMC Ultra32 in EISA Slot %d, Media: %s, %s IRQs.\n", | ||
195 | ioaddr >> 12, ifmap[media], | ||
196 | (edge ? "Edge Triggered" : "Level Sensitive")); | ||
197 | |||
198 | idreg = inb(ioaddr + 7); | ||
199 | reg4 = inb(ioaddr + 4) & 0x7f; | ||
200 | |||
201 | /* Check the ID nibble. */ | ||
202 | if ((idreg & 0xf0) != 0x20) { /* SMC Ultra */ | ||
203 | retval = -ENODEV; | ||
204 | goto out; | ||
205 | } | ||
206 | |||
207 | /* Select the station address register set. */ | ||
208 | outb(reg4, ioaddr + 4); | ||
209 | |||
210 | for (i = 0; i < 8; i++) | ||
211 | checksum += inb(ioaddr + 8 + i); | ||
212 | if ((checksum & 0xff) != 0xff) { | ||
213 | retval = -ENODEV; | ||
214 | goto out; | ||
215 | } | ||
216 | |||
217 | if (ei_debug && version_printed++ == 0) | ||
218 | printk(version); | ||
219 | |||
220 | model_name = "SMC Ultra32"; | ||
221 | |||
222 | for (i = 0; i < 6; i++) | ||
223 | dev->dev_addr[i] = inb(ioaddr + 8 + i); | ||
224 | |||
225 | printk("%s: %s at 0x%X, %pM", | ||
226 | dev->name, model_name, ioaddr, dev->dev_addr); | ||
227 | |||
228 | /* Switch from the station address to the alternate register set and | ||
229 | read the useful registers there. */ | ||
230 | outb(0x80 | reg4, ioaddr + 4); | ||
231 | |||
232 | /* Enable FINE16 mode to avoid BIOS ROM width mismatches @ reboot. */ | ||
233 | outb(0x80 | inb(ioaddr + 0x0c), ioaddr + 0x0c); | ||
234 | |||
235 | /* Reset RAM addr. */ | ||
236 | outb(0x00, ioaddr + 0x0b); | ||
237 | |||
238 | /* Switch back to the station address register set so that the | ||
239 | MS-DOS driver can find the card after a warm boot. */ | ||
240 | outb(reg4, ioaddr + 4); | ||
241 | |||
242 | if ((inb(ioaddr + ULTRA32_CFG5) & 0x40) == 0) { | ||
243 | printk("\nsmc-ultra32: Card RAM is disabled! " | ||
244 | "Run EISA config utility.\n"); | ||
245 | retval = -ENODEV; | ||
246 | goto out; | ||
247 | } | ||
248 | if ((inb(ioaddr + ULTRA32_CFG2) & 0x04) == 0) | ||
249 | printk("\nsmc-ultra32: Ignoring Bus-Master enable bit. " | ||
250 | "Run EISA config utility.\n"); | ||
251 | |||
252 | if (dev->irq < 2) { | ||
253 | unsigned char irqmap[] = {0, 9, 3, 5, 7, 10, 11, 15}; | ||
254 | int irq = irqmap[inb(ioaddr + ULTRA32_CFG5) & 0x07]; | ||
255 | if (irq == 0) { | ||
256 | printk(", failed to detect IRQ line.\n"); | ||
257 | retval = -EAGAIN; | ||
258 | goto out; | ||
259 | } | ||
260 | dev->irq = irq; | ||
261 | } | ||
262 | |||
263 | /* The 8390 isn't at the base address, so fake the offset */ | ||
264 | dev->base_addr = ioaddr + ULTRA32_NIC_OFFSET; | ||
265 | |||
266 | /* Save RAM address in the unused reg0 to avoid excess inb's. */ | ||
267 | ei_status.reg0 = inb(ioaddr + ULTRA32_CFG3) & 0xfc; | ||
268 | |||
269 | dev->mem_start = 0xc0000 + ((ei_status.reg0 & 0x7c) << 11); | ||
270 | |||
271 | ei_status.name = model_name; | ||
272 | ei_status.word16 = 1; | ||
273 | ei_status.tx_start_page = 0; | ||
274 | ei_status.rx_start_page = TX_PAGES; | ||
275 | /* All Ultra32 cards have 32KB memory with an 8KB window. */ | ||
276 | ei_status.stop_page = 128; | ||
277 | |||
278 | ei_status.mem = ioremap(dev->mem_start, 0x2000); | ||
279 | if (!ei_status.mem) { | ||
280 | printk(", failed to ioremap.\n"); | ||
281 | retval = -ENOMEM; | ||
282 | goto out; | ||
283 | } | ||
284 | dev->mem_end = dev->mem_start + 0x1fff; | ||
285 | |||
286 | printk(", IRQ %d, 32KB memory, 8KB window at 0x%lx-0x%lx.\n", | ||
287 | dev->irq, dev->mem_start, dev->mem_end); | ||
288 | ei_status.block_input = &ultra32_block_input; | ||
289 | ei_status.block_output = &ultra32_block_output; | ||
290 | ei_status.get_8390_hdr = &ultra32_get_8390_hdr; | ||
291 | ei_status.reset_8390 = &ultra32_reset_8390; | ||
292 | |||
293 | dev->netdev_ops = &ultra32_netdev_ops; | ||
294 | NS8390_init(dev, 0); | ||
295 | |||
296 | return 0; | ||
297 | out: | ||
298 | release_region(ioaddr, ULTRA32_IO_EXTENT); | ||
299 | return retval; | ||
300 | } | ||
301 | |||
302 | static int ultra32_open(struct net_device *dev) | ||
303 | { | ||
304 | int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC addr */ | ||
305 | int irq_flags = (inb(ioaddr + ULTRA32_CFG5) & 0x08) ? 0 : IRQF_SHARED; | ||
306 | int retval; | ||
307 | |||
308 | retval = request_irq(dev->irq, ei_interrupt, irq_flags, dev->name, dev); | ||
309 | if (retval) | ||
310 | return retval; | ||
311 | |||
312 | outb(ULTRA32_MEMENB, ioaddr); /* Enable Shared Memory. */ | ||
313 | outb(0x80, ioaddr + ULTRA32_CFG6); /* Enable Interrupts. */ | ||
314 | outb(0x84, ioaddr + 5); /* Enable MEM16 & Disable Bus Master. */ | ||
315 | outb(0x01, ioaddr + 6); /* Enable Interrupts. */ | ||
316 | /* Set the early receive warning level in window 0 high enough not | ||
317 | to receive ERW interrupts. */ | ||
318 | outb_p(E8390_NODMA+E8390_PAGE0, dev->base_addr); | ||
319 | outb(0xff, dev->base_addr + EN0_ERWCNT); | ||
320 | ei_open(dev); | ||
321 | return 0; | ||
322 | } | ||
323 | |||
324 | static int ultra32_close(struct net_device *dev) | ||
325 | { | ||
326 | int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* CMDREG */ | ||
327 | |||
328 | netif_stop_queue(dev); | ||
329 | |||
330 | if (ei_debug > 1) | ||
331 | printk("%s: Shutting down ethercard.\n", dev->name); | ||
332 | |||
333 | outb(0x00, ioaddr + ULTRA32_CFG6); /* Disable Interrupts. */ | ||
334 | outb(0x00, ioaddr + 6); /* Disable interrupts. */ | ||
335 | free_irq(dev->irq, dev); | ||
336 | |||
337 | NS8390_init(dev, 0); | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static void ultra32_reset_8390(struct net_device *dev) | ||
343 | { | ||
344 | int ioaddr = dev->base_addr - ULTRA32_NIC_OFFSET; /* ASIC base addr */ | ||
345 | |||
346 | outb(ULTRA32_RESET, ioaddr); | ||
347 | if (ei_debug > 1) printk("resetting Ultra32, t=%ld...", jiffies); | ||
348 | ei_status.txing = 0; | ||
349 | |||
350 | outb(ULTRA32_MEMENB, ioaddr); /* Enable Shared Memory. */ | ||
351 | outb(0x80, ioaddr + ULTRA32_CFG6); /* Enable Interrupts. */ | ||
352 | outb(0x84, ioaddr + 5); /* Enable MEM16 & Disable Bus Master. */ | ||
353 | outb(0x01, ioaddr + 6); /* Enable Interrupts. */ | ||
354 | if (ei_debug > 1) printk("reset done\n"); | ||
355 | } | ||
356 | |||
357 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
358 | we don't need to be concerned with ring wrap as the header will be at | ||
359 | the start of a page, so we optimize accordingly. */ | ||
360 | |||
361 | static void ultra32_get_8390_hdr(struct net_device *dev, | ||
362 | struct e8390_pkt_hdr *hdr, | ||
363 | int ring_page) | ||
364 | { | ||
365 | void __iomem *hdr_start = ei_status.mem + ((ring_page & 0x1f) << 8); | ||
366 | unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3; | ||
367 | |||
368 | /* Select correct 8KB Window. */ | ||
369 | outb(ei_status.reg0 | ((ring_page & 0x60) >> 5), RamReg); | ||
370 | |||
371 | #ifdef __BIG_ENDIAN | ||
372 | /* Officially this is what we are doing, but the readl() is faster */ | ||
373 | /* unfortunately it isn't endian aware of the struct */ | ||
374 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
375 | hdr->count = le16_to_cpu(hdr->count); | ||
376 | #else | ||
377 | ((unsigned int*)hdr)[0] = readl(hdr_start); | ||
378 | #endif | ||
379 | } | ||
380 | |||
381 | /* Block input and output are easy on shared memory ethercards, the only | ||
382 | complication is when the ring buffer wraps, or in this case, when a | ||
383 | packet spans an 8KB boundary. Note that the current 8KB segment is | ||
384 | already set by the get_8390_hdr routine. */ | ||
385 | |||
386 | static void ultra32_block_input(struct net_device *dev, | ||
387 | int count, | ||
388 | struct sk_buff *skb, | ||
389 | int ring_offset) | ||
390 | { | ||
391 | void __iomem *xfer_start = ei_status.mem + (ring_offset & 0x1fff); | ||
392 | unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3; | ||
393 | |||
394 | if ((ring_offset & ~0x1fff) != ((ring_offset + count - 1) & ~0x1fff)) { | ||
395 | int semi_count = 8192 - (ring_offset & 0x1FFF); | ||
396 | memcpy_fromio(skb->data, xfer_start, semi_count); | ||
397 | count -= semi_count; | ||
398 | if (ring_offset < 96*256) { | ||
399 | /* Select next 8KB Window. */ | ||
400 | ring_offset += semi_count; | ||
401 | outb(ei_status.reg0 | ((ring_offset & 0x6000) >> 13), RamReg); | ||
402 | memcpy_fromio(skb->data + semi_count, ei_status.mem, count); | ||
403 | } else { | ||
404 | /* Select first 8KB Window. */ | ||
405 | outb(ei_status.reg0, RamReg); | ||
406 | memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); | ||
407 | } | ||
408 | } else { | ||
409 | memcpy_fromio(skb->data, xfer_start, count); | ||
410 | } | ||
411 | } | ||
412 | |||
413 | static void ultra32_block_output(struct net_device *dev, | ||
414 | int count, | ||
415 | const unsigned char *buf, | ||
416 | int start_page) | ||
417 | { | ||
418 | void __iomem *xfer_start = ei_status.mem + (start_page<<8); | ||
419 | unsigned int RamReg = dev->base_addr - ULTRA32_NIC_OFFSET + ULTRA32_CFG3; | ||
420 | |||
421 | /* Select first 8KB Window. */ | ||
422 | outb(ei_status.reg0, RamReg); | ||
423 | |||
424 | memcpy_toio(xfer_start, buf, count); | ||
425 | } | ||
426 | |||
427 | #ifdef MODULE | ||
428 | #define MAX_ULTRA32_CARDS 4 /* Max number of Ultra cards per module */ | ||
429 | static struct net_device *dev_ultra[MAX_ULTRA32_CARDS]; | ||
430 | |||
431 | MODULE_DESCRIPTION("SMC Ultra32 EISA ethernet driver"); | ||
432 | MODULE_LICENSE("GPL"); | ||
433 | |||
434 | int __init init_module(void) | ||
435 | { | ||
436 | int this_dev, found = 0; | ||
437 | |||
438 | for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) { | ||
439 | struct net_device *dev = ultra32_probe(-1); | ||
440 | if (IS_ERR(dev)) | ||
441 | break; | ||
442 | dev_ultra[found++] = dev; | ||
443 | } | ||
444 | if (found) | ||
445 | return 0; | ||
446 | printk(KERN_WARNING "smc-ultra32.c: No SMC Ultra32 found.\n"); | ||
447 | return -ENXIO; | ||
448 | } | ||
449 | |||
450 | void __exit cleanup_module(void) | ||
451 | { | ||
452 | int this_dev; | ||
453 | |||
454 | for (this_dev = 0; this_dev < MAX_ULTRA32_CARDS; this_dev++) { | ||
455 | struct net_device *dev = dev_ultra[this_dev]; | ||
456 | if (dev) { | ||
457 | unregister_netdev(dev); | ||
458 | cleanup_card(dev); | ||
459 | free_netdev(dev); | ||
460 | } | ||
461 | } | ||
462 | } | ||
463 | #endif /* MODULE */ | ||
464 | |||
diff --git a/drivers/net/ethernet/8390/stnic.c b/drivers/net/ethernet/8390/stnic.c new file mode 100644 index 000000000000..d85f0a84bc7b --- /dev/null +++ b/drivers/net/ethernet/8390/stnic.c | |||
@@ -0,0 +1,294 @@ | |||
1 | /* stnic.c : A SH7750 specific part of driver for NS DP83902A ST-NIC. | ||
2 | * | ||
3 | * This file is subject to the terms and conditions of the GNU General Public | ||
4 | * License. See the file "COPYING" in the main directory of this archive | ||
5 | * for more details. | ||
6 | * | ||
7 | * Copyright (C) 1999 kaz Kojima | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/errno.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/ioport.h> | ||
15 | #include <linux/netdevice.h> | ||
16 | #include <linux/etherdevice.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/delay.h> | ||
19 | |||
20 | #include <asm/system.h> | ||
21 | #include <asm/io.h> | ||
22 | #include <mach-se/mach/se.h> | ||
23 | #include <asm/machvec.h> | ||
24 | #ifdef CONFIG_SH_STANDARD_BIOS | ||
25 | #include <asm/sh_bios.h> | ||
26 | #endif | ||
27 | |||
28 | #include "8390.h" | ||
29 | |||
30 | #define DRV_NAME "stnic" | ||
31 | |||
32 | #define byte unsigned char | ||
33 | #define half unsigned short | ||
34 | #define word unsigned int | ||
35 | #define vbyte volatile unsigned char | ||
36 | #define vhalf volatile unsigned short | ||
37 | #define vword volatile unsigned int | ||
38 | |||
39 | #define STNIC_RUN 0x01 /* 1 == Run, 0 == reset. */ | ||
40 | |||
41 | #define START_PG 0 /* First page of TX buffer */ | ||
42 | #define STOP_PG 128 /* Last page +1 of RX ring */ | ||
43 | |||
44 | /* Alias */ | ||
45 | #define STNIC_CR E8390_CMD | ||
46 | #define PG0_RSAR0 EN0_RSARLO | ||
47 | #define PG0_RSAR1 EN0_RSARHI | ||
48 | #define PG0_RBCR0 EN0_RCNTLO | ||
49 | #define PG0_RBCR1 EN0_RCNTHI | ||
50 | |||
51 | #define CR_RRD E8390_RREAD | ||
52 | #define CR_RWR E8390_RWRITE | ||
53 | #define CR_PG0 E8390_PAGE0 | ||
54 | #define CR_STA E8390_START | ||
55 | #define CR_RDMA E8390_NODMA | ||
56 | |||
57 | /* FIXME! YOU MUST SET YOUR OWN ETHER ADDRESS. */ | ||
58 | static byte stnic_eadr[6] = | ||
59 | {0x00, 0xc0, 0x6e, 0x00, 0x00, 0x07}; | ||
60 | |||
61 | static struct net_device *stnic_dev; | ||
62 | |||
63 | static void stnic_reset (struct net_device *dev); | ||
64 | static void stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
65 | int ring_page); | ||
66 | static void stnic_block_input (struct net_device *dev, int count, | ||
67 | struct sk_buff *skb , int ring_offset); | ||
68 | static void stnic_block_output (struct net_device *dev, int count, | ||
69 | const unsigned char *buf, int start_page); | ||
70 | |||
71 | static void stnic_init (struct net_device *dev); | ||
72 | |||
73 | /* SH7750 specific read/write io. */ | ||
74 | static inline void | ||
75 | STNIC_DELAY (void) | ||
76 | { | ||
77 | vword trash; | ||
78 | trash = *(vword *) 0xa0000000; | ||
79 | trash = *(vword *) 0xa0000000; | ||
80 | trash = *(vword *) 0xa0000000; | ||
81 | } | ||
82 | |||
83 | static inline byte | ||
84 | STNIC_READ (int reg) | ||
85 | { | ||
86 | byte val; | ||
87 | |||
88 | val = (*(vhalf *) (PA_83902 + ((reg) << 1)) >> 8) & 0xff; | ||
89 | STNIC_DELAY (); | ||
90 | return val; | ||
91 | } | ||
92 | |||
93 | static inline void | ||
94 | STNIC_WRITE (int reg, byte val) | ||
95 | { | ||
96 | *(vhalf *) (PA_83902 + ((reg) << 1)) = ((half) (val) << 8); | ||
97 | STNIC_DELAY (); | ||
98 | } | ||
99 | |||
100 | static int __init stnic_probe(void) | ||
101 | { | ||
102 | struct net_device *dev; | ||
103 | int i, err; | ||
104 | |||
105 | /* If we are not running on a SolutionEngine, give up now */ | ||
106 | if (! MACH_SE) | ||
107 | return -ENODEV; | ||
108 | |||
109 | /* New style probing API */ | ||
110 | dev = alloc_ei_netdev(); | ||
111 | if (!dev) | ||
112 | return -ENOMEM; | ||
113 | |||
114 | #ifdef CONFIG_SH_STANDARD_BIOS | ||
115 | sh_bios_get_node_addr (stnic_eadr); | ||
116 | #endif | ||
117 | for (i = 0; i < ETHER_ADDR_LEN; i++) | ||
118 | dev->dev_addr[i] = stnic_eadr[i]; | ||
119 | |||
120 | /* Set the base address to point to the NIC, not the "real" base! */ | ||
121 | dev->base_addr = 0x1000; | ||
122 | dev->irq = IRQ_STNIC; | ||
123 | dev->netdev_ops = &ei_netdev_ops; | ||
124 | |||
125 | /* Snarf the interrupt now. There's no point in waiting since we cannot | ||
126 | share and the board will usually be enabled. */ | ||
127 | err = request_irq (dev->irq, ei_interrupt, 0, DRV_NAME, dev); | ||
128 | if (err) { | ||
129 | printk (KERN_EMERG " unable to get IRQ %d.\n", dev->irq); | ||
130 | free_netdev(dev); | ||
131 | return err; | ||
132 | } | ||
133 | |||
134 | ei_status.name = dev->name; | ||
135 | ei_status.word16 = 1; | ||
136 | #ifdef __LITTLE_ENDIAN__ | ||
137 | ei_status.bigendian = 0; | ||
138 | #else | ||
139 | ei_status.bigendian = 1; | ||
140 | #endif | ||
141 | ei_status.tx_start_page = START_PG; | ||
142 | ei_status.rx_start_page = START_PG + TX_PAGES; | ||
143 | ei_status.stop_page = STOP_PG; | ||
144 | |||
145 | ei_status.reset_8390 = &stnic_reset; | ||
146 | ei_status.get_8390_hdr = &stnic_get_hdr; | ||
147 | ei_status.block_input = &stnic_block_input; | ||
148 | ei_status.block_output = &stnic_block_output; | ||
149 | |||
150 | stnic_init (dev); | ||
151 | |||
152 | err = register_netdev(dev); | ||
153 | if (err) { | ||
154 | free_irq(dev->irq, dev); | ||
155 | free_netdev(dev); | ||
156 | return err; | ||
157 | } | ||
158 | stnic_dev = dev; | ||
159 | |||
160 | printk (KERN_INFO "NS ST-NIC 83902A\n"); | ||
161 | |||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | static void | ||
166 | stnic_reset (struct net_device *dev) | ||
167 | { | ||
168 | *(vhalf *) PA_83902_RST = 0; | ||
169 | udelay (5); | ||
170 | if (ei_debug > 1) | ||
171 | printk (KERN_WARNING "8390 reset done (%ld).\n", jiffies); | ||
172 | *(vhalf *) PA_83902_RST = ~0; | ||
173 | udelay (5); | ||
174 | } | ||
175 | |||
176 | static void | ||
177 | stnic_get_hdr (struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
178 | int ring_page) | ||
179 | { | ||
180 | half buf[2]; | ||
181 | |||
182 | STNIC_WRITE (PG0_RSAR0, 0); | ||
183 | STNIC_WRITE (PG0_RSAR1, ring_page); | ||
184 | STNIC_WRITE (PG0_RBCR0, 4); | ||
185 | STNIC_WRITE (PG0_RBCR1, 0); | ||
186 | STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA); | ||
187 | |||
188 | buf[0] = *(vhalf *) PA_83902_IF; | ||
189 | STNIC_DELAY (); | ||
190 | buf[1] = *(vhalf *) PA_83902_IF; | ||
191 | STNIC_DELAY (); | ||
192 | hdr->next = buf[0] >> 8; | ||
193 | hdr->status = buf[0] & 0xff; | ||
194 | #ifdef __LITTLE_ENDIAN__ | ||
195 | hdr->count = buf[1]; | ||
196 | #else | ||
197 | hdr->count = ((buf[1] >> 8) & 0xff) | (buf[1] << 8); | ||
198 | #endif | ||
199 | |||
200 | if (ei_debug > 1) | ||
201 | printk (KERN_DEBUG "ring %x status %02x next %02x count %04x.\n", | ||
202 | ring_page, hdr->status, hdr->next, hdr->count); | ||
203 | |||
204 | STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA); | ||
205 | } | ||
206 | |||
207 | /* Block input and output, similar to the Crynwr packet driver. If you are | ||
208 | porting to a new ethercard look at the packet driver source for hints. | ||
209 | The HP LAN doesn't use shared memory -- we put the packet | ||
210 | out through the "remote DMA" dataport. */ | ||
211 | |||
212 | static void | ||
213 | stnic_block_input (struct net_device *dev, int length, struct sk_buff *skb, | ||
214 | int offset) | ||
215 | { | ||
216 | char *buf = skb->data; | ||
217 | half val; | ||
218 | |||
219 | STNIC_WRITE (PG0_RSAR0, offset & 0xff); | ||
220 | STNIC_WRITE (PG0_RSAR1, offset >> 8); | ||
221 | STNIC_WRITE (PG0_RBCR0, length & 0xff); | ||
222 | STNIC_WRITE (PG0_RBCR1, length >> 8); | ||
223 | STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA); | ||
224 | |||
225 | if (length & 1) | ||
226 | length++; | ||
227 | |||
228 | while (length > 0) | ||
229 | { | ||
230 | val = *(vhalf *) PA_83902_IF; | ||
231 | #ifdef __LITTLE_ENDIAN__ | ||
232 | *buf++ = val & 0xff; | ||
233 | *buf++ = val >> 8; | ||
234 | #else | ||
235 | *buf++ = val >> 8; | ||
236 | *buf++ = val & 0xff; | ||
237 | #endif | ||
238 | STNIC_DELAY (); | ||
239 | length -= sizeof (half); | ||
240 | } | ||
241 | |||
242 | STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA); | ||
243 | } | ||
244 | |||
245 | static void | ||
246 | stnic_block_output (struct net_device *dev, int length, | ||
247 | const unsigned char *buf, int output_page) | ||
248 | { | ||
249 | STNIC_WRITE (PG0_RBCR0, 1); /* Write non-zero value */ | ||
250 | STNIC_WRITE (STNIC_CR, CR_RRD | CR_PG0 | CR_STA); | ||
251 | STNIC_DELAY (); | ||
252 | |||
253 | STNIC_WRITE (PG0_RBCR0, length & 0xff); | ||
254 | STNIC_WRITE (PG0_RBCR1, length >> 8); | ||
255 | STNIC_WRITE (PG0_RSAR0, 0); | ||
256 | STNIC_WRITE (PG0_RSAR1, output_page); | ||
257 | STNIC_WRITE (STNIC_CR, CR_RWR | CR_PG0 | CR_STA); | ||
258 | |||
259 | if (length & 1) | ||
260 | length++; | ||
261 | |||
262 | while (length > 0) | ||
263 | { | ||
264 | #ifdef __LITTLE_ENDIAN__ | ||
265 | *(vhalf *) PA_83902_IF = ((half) buf[1] << 8) | buf[0]; | ||
266 | #else | ||
267 | *(vhalf *) PA_83902_IF = ((half) buf[0] << 8) | buf[1]; | ||
268 | #endif | ||
269 | STNIC_DELAY (); | ||
270 | buf += sizeof (half); | ||
271 | length -= sizeof (half); | ||
272 | } | ||
273 | |||
274 | STNIC_WRITE (STNIC_CR, CR_RDMA | CR_PG0 | CR_STA); | ||
275 | } | ||
276 | |||
277 | /* This function resets the STNIC if something screws up. */ | ||
278 | static void | ||
279 | stnic_init (struct net_device *dev) | ||
280 | { | ||
281 | stnic_reset (dev); | ||
282 | NS8390_init (dev, 0); | ||
283 | } | ||
284 | |||
285 | static void __exit stnic_cleanup(void) | ||
286 | { | ||
287 | unregister_netdev(stnic_dev); | ||
288 | free_irq(stnic_dev->irq, stnic_dev); | ||
289 | free_netdev(stnic_dev); | ||
290 | } | ||
291 | |||
292 | module_init(stnic_probe); | ||
293 | module_exit(stnic_cleanup); | ||
294 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/ethernet/8390/wd.c b/drivers/net/ethernet/8390/wd.c new file mode 100644 index 000000000000..8831a3393ecf --- /dev/null +++ b/drivers/net/ethernet/8390/wd.c | |||
@@ -0,0 +1,567 @@ | |||
1 | /* wd.c: A WD80x3 ethernet driver for linux. */ | ||
2 | /* | ||
3 | Written 1993-94 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 | This is a driver for WD8003 and WD8013 "compatible" ethercards. | ||
17 | |||
18 | Thanks to Russ Nelson (nelson@crnwyr.com) for loaning me a WD8013. | ||
19 | |||
20 | Changelog: | ||
21 | |||
22 | Paul Gortmaker : multiple card support for module users, support | ||
23 | for non-standard memory sizes. | ||
24 | |||
25 | |||
26 | */ | ||
27 | |||
28 | static const char version[] = | ||
29 | "wd.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; | ||
30 | |||
31 | #include <linux/module.h> | ||
32 | #include <linux/kernel.h> | ||
33 | #include <linux/errno.h> | ||
34 | #include <linux/string.h> | ||
35 | #include <linux/init.h> | ||
36 | #include <linux/interrupt.h> | ||
37 | #include <linux/delay.h> | ||
38 | #include <linux/netdevice.h> | ||
39 | #include <linux/etherdevice.h> | ||
40 | |||
41 | #include <asm/io.h> | ||
42 | #include <asm/system.h> | ||
43 | |||
44 | #include "8390.h" | ||
45 | |||
46 | #define DRV_NAME "wd" | ||
47 | |||
48 | /* A zero-terminated list of I/O addresses to be probed. */ | ||
49 | static unsigned int wd_portlist[] __initdata = | ||
50 | {0x300, 0x280, 0x380, 0x240, 0}; | ||
51 | |||
52 | static int wd_probe1(struct net_device *dev, int ioaddr); | ||
53 | |||
54 | static int wd_open(struct net_device *dev); | ||
55 | static void wd_reset_8390(struct net_device *dev); | ||
56 | static void wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, | ||
57 | int ring_page); | ||
58 | static void wd_block_input(struct net_device *dev, int count, | ||
59 | struct sk_buff *skb, int ring_offset); | ||
60 | static void wd_block_output(struct net_device *dev, int count, | ||
61 | const unsigned char *buf, int start_page); | ||
62 | static int wd_close(struct net_device *dev); | ||
63 | |||
64 | |||
65 | #define WD_START_PG 0x00 /* First page of TX buffer */ | ||
66 | #define WD03_STOP_PG 0x20 /* Last page +1 of RX ring */ | ||
67 | #define WD13_STOP_PG 0x40 /* Last page +1 of RX ring */ | ||
68 | |||
69 | #define WD_CMDREG 0 /* Offset to ASIC command register. */ | ||
70 | #define WD_RESET 0x80 /* Board reset, in WD_CMDREG. */ | ||
71 | #define WD_MEMENB 0x40 /* Enable the shared memory. */ | ||
72 | #define WD_CMDREG5 5 /* Offset to 16-bit-only ASIC register 5. */ | ||
73 | #define ISA16 0x80 /* Enable 16 bit access from the ISA bus. */ | ||
74 | #define NIC16 0x40 /* Enable 16 bit access from the 8390. */ | ||
75 | #define WD_NIC_OFFSET 16 /* Offset to the 8390 from the base_addr. */ | ||
76 | #define WD_IO_EXTENT 32 | ||
77 | |||
78 | |||
79 | /* Probe for the WD8003 and WD8013. These cards have the station | ||
80 | address PROM at I/O ports <base>+8 to <base>+13, with a checksum | ||
81 | following. A Soundblaster can have the same checksum as an WDethercard, | ||
82 | so we have an extra exclusionary check for it. | ||
83 | |||
84 | The wd_probe1() routine initializes the card and fills the | ||
85 | station address field. */ | ||
86 | |||
87 | static int __init do_wd_probe(struct net_device *dev) | ||
88 | { | ||
89 | int i; | ||
90 | struct resource *r; | ||
91 | int base_addr = dev->base_addr; | ||
92 | int irq = dev->irq; | ||
93 | int mem_start = dev->mem_start; | ||
94 | int mem_end = dev->mem_end; | ||
95 | |||
96 | if (base_addr > 0x1ff) { /* Check a user specified location. */ | ||
97 | r = request_region(base_addr, WD_IO_EXTENT, "wd-probe"); | ||
98 | if ( r == NULL) | ||
99 | return -EBUSY; | ||
100 | i = wd_probe1(dev, base_addr); | ||
101 | if (i != 0) | ||
102 | release_region(base_addr, WD_IO_EXTENT); | ||
103 | else | ||
104 | r->name = dev->name; | ||
105 | return i; | ||
106 | } | ||
107 | else if (base_addr != 0) /* Don't probe at all. */ | ||
108 | return -ENXIO; | ||
109 | |||
110 | for (i = 0; wd_portlist[i]; i++) { | ||
111 | int ioaddr = wd_portlist[i]; | ||
112 | r = request_region(ioaddr, WD_IO_EXTENT, "wd-probe"); | ||
113 | if (r == NULL) | ||
114 | continue; | ||
115 | if (wd_probe1(dev, ioaddr) == 0) { | ||
116 | r->name = dev->name; | ||
117 | return 0; | ||
118 | } | ||
119 | release_region(ioaddr, WD_IO_EXTENT); | ||
120 | dev->irq = irq; | ||
121 | dev->mem_start = mem_start; | ||
122 | dev->mem_end = mem_end; | ||
123 | } | ||
124 | |||
125 | return -ENODEV; | ||
126 | } | ||
127 | |||
128 | #ifndef MODULE | ||
129 | struct net_device * __init wd_probe(int unit) | ||
130 | { | ||
131 | struct net_device *dev = alloc_ei_netdev(); | ||
132 | int err; | ||
133 | |||
134 | if (!dev) | ||
135 | return ERR_PTR(-ENOMEM); | ||
136 | |||
137 | sprintf(dev->name, "eth%d", unit); | ||
138 | netdev_boot_setup_check(dev); | ||
139 | |||
140 | err = do_wd_probe(dev); | ||
141 | if (err) | ||
142 | goto out; | ||
143 | return dev; | ||
144 | out: | ||
145 | free_netdev(dev); | ||
146 | return ERR_PTR(err); | ||
147 | } | ||
148 | #endif | ||
149 | |||
150 | static const struct net_device_ops wd_netdev_ops = { | ||
151 | .ndo_open = wd_open, | ||
152 | .ndo_stop = wd_close, | ||
153 | .ndo_start_xmit = ei_start_xmit, | ||
154 | .ndo_tx_timeout = ei_tx_timeout, | ||
155 | .ndo_get_stats = ei_get_stats, | ||
156 | .ndo_set_multicast_list = ei_set_multicast_list, | ||
157 | .ndo_validate_addr = eth_validate_addr, | ||
158 | .ndo_set_mac_address = eth_mac_addr, | ||
159 | .ndo_change_mtu = eth_change_mtu, | ||
160 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
161 | .ndo_poll_controller = ei_poll, | ||
162 | #endif | ||
163 | }; | ||
164 | |||
165 | static int __init wd_probe1(struct net_device *dev, int ioaddr) | ||
166 | { | ||
167 | int i; | ||
168 | int err; | ||
169 | int checksum = 0; | ||
170 | int ancient = 0; /* An old card without config registers. */ | ||
171 | int word16 = 0; /* 0 = 8 bit, 1 = 16 bit */ | ||
172 | const char *model_name; | ||
173 | static unsigned version_printed; | ||
174 | |||
175 | for (i = 0; i < 8; i++) | ||
176 | checksum += inb(ioaddr + 8 + i); | ||
177 | if (inb(ioaddr + 8) == 0xff /* Extra check to avoid soundcard. */ | ||
178 | || inb(ioaddr + 9) == 0xff | ||
179 | || (checksum & 0xff) != 0xFF) | ||
180 | return -ENODEV; | ||
181 | |||
182 | /* Check for semi-valid mem_start/end values if supplied. */ | ||
183 | if ((dev->mem_start % 0x2000) || (dev->mem_end % 0x2000)) { | ||
184 | printk(KERN_WARNING "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n"); | ||
185 | dev->mem_start = 0; | ||
186 | dev->mem_end = 0; | ||
187 | } | ||
188 | |||
189 | if (ei_debug && version_printed++ == 0) | ||
190 | printk(version); | ||
191 | |||
192 | for (i = 0; i < 6; i++) | ||
193 | dev->dev_addr[i] = inb(ioaddr + 8 + i); | ||
194 | |||
195 | printk("%s: WD80x3 at %#3x, %pM", | ||
196 | dev->name, ioaddr, dev->dev_addr); | ||
197 | |||
198 | /* The following PureData probe code was contributed by | ||
199 | Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata does software | ||
200 | configuration differently from others so we have to check for them. | ||
201 | This detects an 8 bit, 16 bit or dumb (Toshiba, jumpered) card. | ||
202 | */ | ||
203 | if (inb(ioaddr+0) == 'P' && inb(ioaddr+1) == 'D') { | ||
204 | unsigned char reg5 = inb(ioaddr+5); | ||
205 | |||
206 | switch (inb(ioaddr+2)) { | ||
207 | case 0x03: word16 = 0; model_name = "PDI8023-8"; break; | ||
208 | case 0x05: word16 = 0; model_name = "PDUC8023"; break; | ||
209 | case 0x0a: word16 = 1; model_name = "PDI8023-16"; break; | ||
210 | /* Either 0x01 (dumb) or they've released a new version. */ | ||
211 | default: word16 = 0; model_name = "PDI8023"; break; | ||
212 | } | ||
213 | dev->mem_start = ((reg5 & 0x1c) + 0xc0) << 12; | ||
214 | dev->irq = (reg5 & 0xe0) == 0xe0 ? 10 : (reg5 >> 5) + 1; | ||
215 | } else { /* End of PureData probe */ | ||
216 | /* This method of checking for a 16-bit board is borrowed from the | ||
217 | we.c driver. A simpler method is just to look in ASIC reg. 0x03. | ||
218 | I'm comparing the two method in alpha test to make certain they | ||
219 | return the same result. */ | ||
220 | /* Check for the old 8 bit board - it has register 0/8 aliasing. | ||
221 | Do NOT check i>=6 here -- it hangs the old 8003 boards! */ | ||
222 | for (i = 0; i < 6; i++) | ||
223 | if (inb(ioaddr+i) != inb(ioaddr+8+i)) | ||
224 | break; | ||
225 | if (i >= 6) { | ||
226 | ancient = 1; | ||
227 | model_name = "WD8003-old"; | ||
228 | word16 = 0; | ||
229 | } else { | ||
230 | int tmp = inb(ioaddr+1); /* fiddle with 16bit bit */ | ||
231 | outb( tmp ^ 0x01, ioaddr+1 ); /* attempt to clear 16bit bit */ | ||
232 | if (((inb( ioaddr+1) & 0x01) == 0x01) /* A 16 bit card */ | ||
233 | && (tmp & 0x01) == 0x01 ) { /* In a 16 slot. */ | ||
234 | int asic_reg5 = inb(ioaddr+WD_CMDREG5); | ||
235 | /* Magic to set ASIC to word-wide mode. */ | ||
236 | outb( NIC16 | (asic_reg5&0x1f), ioaddr+WD_CMDREG5); | ||
237 | outb(tmp, ioaddr+1); | ||
238 | model_name = "WD8013"; | ||
239 | word16 = 1; /* We have a 16bit board here! */ | ||
240 | } else { | ||
241 | model_name = "WD8003"; | ||
242 | word16 = 0; | ||
243 | } | ||
244 | outb(tmp, ioaddr+1); /* Restore original reg1 value. */ | ||
245 | } | ||
246 | #ifndef final_version | ||
247 | if ( !ancient && (inb(ioaddr+1) & 0x01) != (word16 & 0x01)) | ||
248 | printk("\nWD80?3: Bus width conflict, %d (probe) != %d (reg report).", | ||
249 | word16 ? 16 : 8, (inb(ioaddr+1) & 0x01) ? 16 : 8); | ||
250 | #endif | ||
251 | } | ||
252 | |||
253 | #if defined(WD_SHMEM) && WD_SHMEM > 0x80000 | ||
254 | /* Allow a compile-time override. */ | ||
255 | dev->mem_start = WD_SHMEM; | ||
256 | #else | ||
257 | if (dev->mem_start == 0) { | ||
258 | /* Sanity and old 8003 check */ | ||
259 | int reg0 = inb(ioaddr); | ||
260 | if (reg0 == 0xff || reg0 == 0) { | ||
261 | /* Future plan: this could check a few likely locations first. */ | ||
262 | dev->mem_start = 0xd0000; | ||
263 | printk(" assigning address %#lx", dev->mem_start); | ||
264 | } else { | ||
265 | int high_addr_bits = inb(ioaddr+WD_CMDREG5) & 0x1f; | ||
266 | /* Some boards don't have the register 5 -- it returns 0xff. */ | ||
267 | if (high_addr_bits == 0x1f || word16 == 0) | ||
268 | high_addr_bits = 0x01; | ||
269 | dev->mem_start = ((reg0&0x3f) << 13) + (high_addr_bits << 19); | ||
270 | } | ||
271 | } | ||
272 | #endif | ||
273 | |||
274 | /* The 8390 isn't at the base address -- the ASIC regs are there! */ | ||
275 | dev->base_addr = ioaddr+WD_NIC_OFFSET; | ||
276 | |||
277 | if (dev->irq < 2) { | ||
278 | static const int irqmap[] = {9, 3, 5, 7, 10, 11, 15, 4}; | ||
279 | int reg1 = inb(ioaddr+1); | ||
280 | int reg4 = inb(ioaddr+4); | ||
281 | if (ancient || reg1 == 0xff) { /* Ack!! No way to read the IRQ! */ | ||
282 | short nic_addr = ioaddr+WD_NIC_OFFSET; | ||
283 | unsigned long irq_mask; | ||
284 | |||
285 | /* We have an old-style ethercard that doesn't report its IRQ | ||
286 | line. Do autoirq to find the IRQ line. Note that this IS NOT | ||
287 | a reliable way to trigger an interrupt. */ | ||
288 | outb_p(E8390_NODMA + E8390_STOP, nic_addr); | ||
289 | outb(0x00, nic_addr+EN0_IMR); /* Disable all intrs. */ | ||
290 | |||
291 | irq_mask = probe_irq_on(); | ||
292 | outb_p(0xff, nic_addr + EN0_IMR); /* Enable all interrupts. */ | ||
293 | outb_p(0x00, nic_addr + EN0_RCNTLO); | ||
294 | outb_p(0x00, nic_addr + EN0_RCNTHI); | ||
295 | outb(E8390_RREAD+E8390_START, nic_addr); /* Trigger it... */ | ||
296 | mdelay(20); | ||
297 | dev->irq = probe_irq_off(irq_mask); | ||
298 | |||
299 | outb_p(0x00, nic_addr+EN0_IMR); /* Mask all intrs. again. */ | ||
300 | |||
301 | if (ei_debug > 2) | ||
302 | printk(" autoirq is %d", dev->irq); | ||
303 | if (dev->irq < 2) | ||
304 | dev->irq = word16 ? 10 : 5; | ||
305 | } else | ||
306 | dev->irq = irqmap[((reg4 >> 5) & 0x03) + (reg1 & 0x04)]; | ||
307 | } else if (dev->irq == 2) /* Fixup bogosity: IRQ2 is really IRQ9 */ | ||
308 | dev->irq = 9; | ||
309 | |||
310 | /* Snarf the interrupt now. There's no point in waiting since we cannot | ||
311 | share and the board will usually be enabled. */ | ||
312 | i = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev); | ||
313 | if (i) { | ||
314 | printk (" unable to get IRQ %d.\n", dev->irq); | ||
315 | return i; | ||
316 | } | ||
317 | |||
318 | /* OK, were are certain this is going to work. Setup the device. */ | ||
319 | ei_status.name = model_name; | ||
320 | ei_status.word16 = word16; | ||
321 | ei_status.tx_start_page = WD_START_PG; | ||
322 | ei_status.rx_start_page = WD_START_PG + TX_PAGES; | ||
323 | |||
324 | /* Don't map in the shared memory until the board is actually opened. */ | ||
325 | |||
326 | /* Some cards (eg WD8003EBT) can be jumpered for more (32k!) memory. */ | ||
327 | if (dev->mem_end != 0) { | ||
328 | ei_status.stop_page = (dev->mem_end - dev->mem_start)/256; | ||
329 | ei_status.priv = dev->mem_end - dev->mem_start; | ||
330 | } else { | ||
331 | ei_status.stop_page = word16 ? WD13_STOP_PG : WD03_STOP_PG; | ||
332 | dev->mem_end = dev->mem_start + (ei_status.stop_page - WD_START_PG)*256; | ||
333 | ei_status.priv = (ei_status.stop_page - WD_START_PG)*256; | ||
334 | } | ||
335 | |||
336 | ei_status.mem = ioremap(dev->mem_start, ei_status.priv); | ||
337 | if (!ei_status.mem) { | ||
338 | free_irq(dev->irq, dev); | ||
339 | return -ENOMEM; | ||
340 | } | ||
341 | |||
342 | printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n", | ||
343 | model_name, dev->irq, dev->mem_start, dev->mem_end-1); | ||
344 | |||
345 | ei_status.reset_8390 = wd_reset_8390; | ||
346 | ei_status.block_input = wd_block_input; | ||
347 | ei_status.block_output = wd_block_output; | ||
348 | ei_status.get_8390_hdr = wd_get_8390_hdr; | ||
349 | |||
350 | dev->netdev_ops = &wd_netdev_ops; | ||
351 | NS8390_init(dev, 0); | ||
352 | |||
353 | #if 1 | ||
354 | /* Enable interrupt generation on softconfig cards -- M.U */ | ||
355 | /* .. but possibly potentially unsafe - Donald */ | ||
356 | if (inb(ioaddr+14) & 0x20) | ||
357 | outb(inb(ioaddr+4)|0x80, ioaddr+4); | ||
358 | #endif | ||
359 | |||
360 | err = register_netdev(dev); | ||
361 | if (err) { | ||
362 | free_irq(dev->irq, dev); | ||
363 | iounmap(ei_status.mem); | ||
364 | } | ||
365 | return err; | ||
366 | } | ||
367 | |||
368 | static int | ||
369 | wd_open(struct net_device *dev) | ||
370 | { | ||
371 | int ioaddr = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ | ||
372 | |||
373 | /* Map in the shared memory. Always set register 0 last to remain | ||
374 | compatible with very old boards. */ | ||
375 | ei_status.reg0 = ((dev->mem_start>>13) & 0x3f) | WD_MEMENB; | ||
376 | ei_status.reg5 = ((dev->mem_start>>19) & 0x1f) | NIC16; | ||
377 | |||
378 | if (ei_status.word16) | ||
379 | outb(ei_status.reg5, ioaddr+WD_CMDREG5); | ||
380 | outb(ei_status.reg0, ioaddr); /* WD_CMDREG */ | ||
381 | |||
382 | return ei_open(dev); | ||
383 | } | ||
384 | |||
385 | static void | ||
386 | wd_reset_8390(struct net_device *dev) | ||
387 | { | ||
388 | int wd_cmd_port = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ | ||
389 | |||
390 | outb(WD_RESET, wd_cmd_port); | ||
391 | if (ei_debug > 1) printk("resetting the WD80x3 t=%lu...", jiffies); | ||
392 | ei_status.txing = 0; | ||
393 | |||
394 | /* Set up the ASIC registers, just in case something changed them. */ | ||
395 | outb((((dev->mem_start>>13) & 0x3f)|WD_MEMENB), wd_cmd_port); | ||
396 | if (ei_status.word16) | ||
397 | outb(NIC16 | ((dev->mem_start>>19) & 0x1f), wd_cmd_port+WD_CMDREG5); | ||
398 | |||
399 | if (ei_debug > 1) printk("reset done\n"); | ||
400 | } | ||
401 | |||
402 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
403 | we don't need to be concerned with ring wrap as the header will be at | ||
404 | the start of a page, so we optimize accordingly. */ | ||
405 | |||
406 | static void | ||
407 | wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page) | ||
408 | { | ||
409 | |||
410 | int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ | ||
411 | void __iomem *hdr_start = ei_status.mem + ((ring_page - WD_START_PG)<<8); | ||
412 | |||
413 | /* We'll always get a 4 byte header read followed by a packet read, so | ||
414 | we enable 16 bit mode before the header, and disable after the body. */ | ||
415 | if (ei_status.word16) | ||
416 | outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5); | ||
417 | |||
418 | #ifdef __BIG_ENDIAN | ||
419 | /* Officially this is what we are doing, but the readl() is faster */ | ||
420 | /* unfortunately it isn't endian aware of the struct */ | ||
421 | memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr)); | ||
422 | hdr->count = le16_to_cpu(hdr->count); | ||
423 | #else | ||
424 | ((unsigned int*)hdr)[0] = readl(hdr_start); | ||
425 | #endif | ||
426 | } | ||
427 | |||
428 | /* Block input and output are easy on shared memory ethercards, and trivial | ||
429 | on the Western digital card where there is no choice of how to do it. | ||
430 | The only complications are that the ring buffer wraps, and need to map | ||
431 | switch between 8- and 16-bit modes. */ | ||
432 | |||
433 | static void | ||
434 | wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset) | ||
435 | { | ||
436 | int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ | ||
437 | unsigned long offset = ring_offset - (WD_START_PG<<8); | ||
438 | void __iomem *xfer_start = ei_status.mem + offset; | ||
439 | |||
440 | if (offset + count > ei_status.priv) { | ||
441 | /* We must wrap the input move. */ | ||
442 | int semi_count = ei_status.priv - offset; | ||
443 | memcpy_fromio(skb->data, xfer_start, semi_count); | ||
444 | count -= semi_count; | ||
445 | memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count); | ||
446 | } else { | ||
447 | /* Packet is in one chunk -- we can copy + cksum. */ | ||
448 | memcpy_fromio(skb->data, xfer_start, count); | ||
449 | } | ||
450 | |||
451 | /* Turn off 16 bit access so that reboot works. ISA brain-damage */ | ||
452 | if (ei_status.word16) | ||
453 | outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5); | ||
454 | } | ||
455 | |||
456 | static void | ||
457 | wd_block_output(struct net_device *dev, int count, const unsigned char *buf, | ||
458 | int start_page) | ||
459 | { | ||
460 | int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ | ||
461 | void __iomem *shmem = ei_status.mem + ((start_page - WD_START_PG)<<8); | ||
462 | |||
463 | |||
464 | if (ei_status.word16) { | ||
465 | /* Turn on and off 16 bit access so that reboot works. */ | ||
466 | outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5); | ||
467 | memcpy_toio(shmem, buf, count); | ||
468 | outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5); | ||
469 | } else | ||
470 | memcpy_toio(shmem, buf, count); | ||
471 | } | ||
472 | |||
473 | |||
474 | static int | ||
475 | wd_close(struct net_device *dev) | ||
476 | { | ||
477 | int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */ | ||
478 | |||
479 | if (ei_debug > 1) | ||
480 | printk("%s: Shutting down ethercard.\n", dev->name); | ||
481 | ei_close(dev); | ||
482 | |||
483 | /* Change from 16-bit to 8-bit shared memory so reboot works. */ | ||
484 | if (ei_status.word16) | ||
485 | outb(ei_status.reg5, wd_cmdreg + WD_CMDREG5 ); | ||
486 | |||
487 | /* And disable the shared memory. */ | ||
488 | outb(ei_status.reg0 & ~WD_MEMENB, wd_cmdreg); | ||
489 | |||
490 | return 0; | ||
491 | } | ||
492 | |||
493 | |||
494 | #ifdef MODULE | ||
495 | #define MAX_WD_CARDS 4 /* Max number of wd cards per module */ | ||
496 | static struct net_device *dev_wd[MAX_WD_CARDS]; | ||
497 | static int io[MAX_WD_CARDS]; | ||
498 | static int irq[MAX_WD_CARDS]; | ||
499 | static int mem[MAX_WD_CARDS]; | ||
500 | static int mem_end[MAX_WD_CARDS]; /* for non std. mem size */ | ||
501 | |||
502 | module_param_array(io, int, NULL, 0); | ||
503 | module_param_array(irq, int, NULL, 0); | ||
504 | module_param_array(mem, int, NULL, 0); | ||
505 | module_param_array(mem_end, int, NULL, 0); | ||
506 | MODULE_PARM_DESC(io, "I/O base address(es)"); | ||
507 | MODULE_PARM_DESC(irq, "IRQ number(s) (ignored for PureData boards)"); | ||
508 | MODULE_PARM_DESC(mem, "memory base address(es)(ignored for PureData boards)"); | ||
509 | MODULE_PARM_DESC(mem_end, "memory end address(es)"); | ||
510 | MODULE_DESCRIPTION("ISA Western Digital wd8003/wd8013 ; SMC Elite, Elite16 ethernet driver"); | ||
511 | MODULE_LICENSE("GPL"); | ||
512 | |||
513 | /* This is set up so that only a single autoprobe takes place per call. | ||
514 | ISA device autoprobes on a running machine are not recommended. */ | ||
515 | |||
516 | int __init init_module(void) | ||
517 | { | ||
518 | struct net_device *dev; | ||
519 | int this_dev, found = 0; | ||
520 | |||
521 | for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) { | ||
522 | if (io[this_dev] == 0) { | ||
523 | if (this_dev != 0) break; /* only autoprobe 1st one */ | ||
524 | printk(KERN_NOTICE "wd.c: Presently autoprobing (not recommended) for a single card.\n"); | ||
525 | } | ||
526 | dev = alloc_ei_netdev(); | ||
527 | if (!dev) | ||
528 | break; | ||
529 | dev->irq = irq[this_dev]; | ||
530 | dev->base_addr = io[this_dev]; | ||
531 | dev->mem_start = mem[this_dev]; | ||
532 | dev->mem_end = mem_end[this_dev]; | ||
533 | if (do_wd_probe(dev) == 0) { | ||
534 | dev_wd[found++] = dev; | ||
535 | continue; | ||
536 | } | ||
537 | free_netdev(dev); | ||
538 | printk(KERN_WARNING "wd.c: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]); | ||
539 | break; | ||
540 | } | ||
541 | if (found) | ||
542 | return 0; | ||
543 | return -ENXIO; | ||
544 | } | ||
545 | |||
546 | static void cleanup_card(struct net_device *dev) | ||
547 | { | ||
548 | free_irq(dev->irq, dev); | ||
549 | release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT); | ||
550 | iounmap(ei_status.mem); | ||
551 | } | ||
552 | |||
553 | void __exit | ||
554 | cleanup_module(void) | ||
555 | { | ||
556 | int this_dev; | ||
557 | |||
558 | for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) { | ||
559 | struct net_device *dev = dev_wd[this_dev]; | ||
560 | if (dev) { | ||
561 | unregister_netdev(dev); | ||
562 | cleanup_card(dev); | ||
563 | free_netdev(dev); | ||
564 | } | ||
565 | } | ||
566 | } | ||
567 | #endif /* MODULE */ | ||
diff --git a/drivers/net/ethernet/8390/zorro8390.c b/drivers/net/ethernet/8390/zorro8390.c new file mode 100644 index 000000000000..15e7751a273c --- /dev/null +++ b/drivers/net/ethernet/8390/zorro8390.c | |||
@@ -0,0 +1,452 @@ | |||
1 | /* | ||
2 | * Amiga Linux/m68k and Linux/PPC Zorro NS8390 Ethernet Driver | ||
3 | * | ||
4 | * (C) Copyright 1998-2000 by some Elitist 680x0 Users(TM) | ||
5 | * | ||
6 | * --------------------------------------------------------------------------- | ||
7 | * | ||
8 | * This program is based on all the other NE2000 drivers for Linux | ||
9 | * | ||
10 | * --------------------------------------------------------------------------- | ||
11 | * | ||
12 | * This file is subject to the terms and conditions of the GNU General Public | ||
13 | * License. See the file COPYING in the main directory of the Linux | ||
14 | * distribution for more details. | ||
15 | * | ||
16 | * --------------------------------------------------------------------------- | ||
17 | * | ||
18 | * The Ariadne II and X-Surf are Zorro-II boards containing Realtek RTL8019AS | ||
19 | * Ethernet Controllers. | ||
20 | */ | ||
21 | |||
22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/netdevice.h> | ||
30 | #include <linux/etherdevice.h> | ||
31 | #include <linux/zorro.h> | ||
32 | #include <linux/jiffies.h> | ||
33 | |||
34 | #include <asm/system.h> | ||
35 | #include <asm/irq.h> | ||
36 | #include <asm/amigaints.h> | ||
37 | #include <asm/amigahw.h> | ||
38 | |||
39 | #define EI_SHIFT(x) (ei_local->reg_offset[x]) | ||
40 | #define ei_inb(port) in_8(port) | ||
41 | #define ei_outb(val, port) out_8(port, val) | ||
42 | #define ei_inb_p(port) in_8(port) | ||
43 | #define ei_outb_p(val, port) out_8(port, val) | ||
44 | |||
45 | static const char version[] = | ||
46 | "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n"; | ||
47 | |||
48 | #include "lib8390.c" | ||
49 | |||
50 | #define DRV_NAME "zorro8390" | ||
51 | |||
52 | #define NE_BASE (dev->base_addr) | ||
53 | #define NE_CMD (0x00 * 2) | ||
54 | #define NE_DATAPORT (0x10 * 2) /* NatSemi-defined port window offset */ | ||
55 | #define NE_RESET (0x1f * 2) /* Issue a read to reset, | ||
56 | * a write to clear. */ | ||
57 | #define NE_IO_EXTENT (0x20 * 2) | ||
58 | |||
59 | #define NE_EN0_ISR (0x07 * 2) | ||
60 | #define NE_EN0_DCFG (0x0e * 2) | ||
61 | |||
62 | #define NE_EN0_RSARLO (0x08 * 2) | ||
63 | #define NE_EN0_RSARHI (0x09 * 2) | ||
64 | #define NE_EN0_RCNTLO (0x0a * 2) | ||
65 | #define NE_EN0_RXCR (0x0c * 2) | ||
66 | #define NE_EN0_TXCR (0x0d * 2) | ||
67 | #define NE_EN0_RCNTHI (0x0b * 2) | ||
68 | #define NE_EN0_IMR (0x0f * 2) | ||
69 | |||
70 | #define NESM_START_PG 0x40 /* First page of TX buffer */ | ||
71 | #define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */ | ||
72 | |||
73 | #define WORDSWAP(a) ((((a) >> 8) & 0xff) | ((a) << 8)) | ||
74 | |||
75 | static struct card_info { | ||
76 | zorro_id id; | ||
77 | const char *name; | ||
78 | unsigned int offset; | ||
79 | } cards[] __devinitdata = { | ||
80 | { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, "Ariadne II", 0x0600 }, | ||
81 | { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, "X-Surf", 0x8600 }, | ||
82 | }; | ||
83 | |||
84 | /* Hard reset the card. This used to pause for the same period that a | ||
85 | * 8390 reset command required, but that shouldn't be necessary. | ||
86 | */ | ||
87 | static void zorro8390_reset_8390(struct net_device *dev) | ||
88 | { | ||
89 | unsigned long reset_start_time = jiffies; | ||
90 | |||
91 | if (ei_debug > 1) | ||
92 | netdev_dbg(dev, "resetting - t=%ld...\n", jiffies); | ||
93 | |||
94 | z_writeb(z_readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET); | ||
95 | |||
96 | ei_status.txing = 0; | ||
97 | ei_status.dmaing = 0; | ||
98 | |||
99 | /* This check _should_not_ be necessary, omit eventually. */ | ||
100 | while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RESET) == 0) | ||
101 | if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) { | ||
102 | netdev_warn(dev, "%s: did not complete\n", __func__); | ||
103 | break; | ||
104 | } | ||
105 | z_writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr */ | ||
106 | } | ||
107 | |||
108 | /* Grab the 8390 specific header. Similar to the block_input routine, but | ||
109 | * we don't need to be concerned with ring wrap as the header will be at | ||
110 | * the start of a page, so we optimize accordingly. | ||
111 | */ | ||
112 | static void zorro8390_get_8390_hdr(struct net_device *dev, | ||
113 | struct e8390_pkt_hdr *hdr, int ring_page) | ||
114 | { | ||
115 | int nic_base = dev->base_addr; | ||
116 | int cnt; | ||
117 | short *ptrs; | ||
118 | |||
119 | /* This *shouldn't* happen. | ||
120 | * If it does, it's the last thing you'll see | ||
121 | */ | ||
122 | if (ei_status.dmaing) { | ||
123 | netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", | ||
124 | __func__, ei_status.dmaing, ei_status.irqlock); | ||
125 | return; | ||
126 | } | ||
127 | |||
128 | ei_status.dmaing |= 0x01; | ||
129 | z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); | ||
130 | z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); | ||
131 | z_writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO); | ||
132 | z_writeb(0, nic_base + NE_EN0_RCNTHI); | ||
133 | z_writeb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */ | ||
134 | z_writeb(ring_page, nic_base + NE_EN0_RSARHI); | ||
135 | z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
136 | |||
137 | ptrs = (short *)hdr; | ||
138 | for (cnt = 0; cnt < sizeof(struct e8390_pkt_hdr) >> 1; cnt++) | ||
139 | *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); | ||
140 | |||
141 | z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ | ||
142 | |||
143 | hdr->count = WORDSWAP(hdr->count); | ||
144 | |||
145 | ei_status.dmaing &= ~0x01; | ||
146 | } | ||
147 | |||
148 | /* Block input and output, similar to the Crynwr packet driver. | ||
149 | * If you are porting to a new ethercard, look at the packet driver source | ||
150 | * for hints. The NEx000 doesn't share the on-board packet memory -- | ||
151 | * you have to put the packet out through the "remote DMA" dataport | ||
152 | * using z_writeb. | ||
153 | */ | ||
154 | static void zorro8390_block_input(struct net_device *dev, int count, | ||
155 | struct sk_buff *skb, int ring_offset) | ||
156 | { | ||
157 | int nic_base = dev->base_addr; | ||
158 | char *buf = skb->data; | ||
159 | short *ptrs; | ||
160 | int cnt; | ||
161 | |||
162 | /* This *shouldn't* happen. | ||
163 | * If it does, it's the last thing you'll see | ||
164 | */ | ||
165 | if (ei_status.dmaing) { | ||
166 | netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", | ||
167 | __func__, ei_status.dmaing, ei_status.irqlock); | ||
168 | return; | ||
169 | } | ||
170 | ei_status.dmaing |= 0x01; | ||
171 | z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD); | ||
172 | z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); | ||
173 | z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); | ||
174 | z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI); | ||
175 | z_writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO); | ||
176 | z_writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI); | ||
177 | z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD); | ||
178 | ptrs = (short *)buf; | ||
179 | for (cnt = 0; cnt < count >> 1; cnt++) | ||
180 | *ptrs++ = z_readw(NE_BASE + NE_DATAPORT); | ||
181 | if (count & 0x01) | ||
182 | buf[count - 1] = z_readb(NE_BASE + NE_DATAPORT); | ||
183 | |||
184 | z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ | ||
185 | ei_status.dmaing &= ~0x01; | ||
186 | } | ||
187 | |||
188 | static void zorro8390_block_output(struct net_device *dev, int count, | ||
189 | const unsigned char *buf, | ||
190 | const int start_page) | ||
191 | { | ||
192 | int nic_base = NE_BASE; | ||
193 | unsigned long dma_start; | ||
194 | short *ptrs; | ||
195 | int cnt; | ||
196 | |||
197 | /* Round the count up for word writes. Do we need to do this? | ||
198 | * What effect will an odd byte count have on the 8390? | ||
199 | * I should check someday. | ||
200 | */ | ||
201 | if (count & 0x01) | ||
202 | count++; | ||
203 | |||
204 | /* This *shouldn't* happen. | ||
205 | * If it does, it's the last thing you'll see | ||
206 | */ | ||
207 | if (ei_status.dmaing) { | ||
208 | netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n", | ||
209 | __func__, ei_status.dmaing, ei_status.irqlock); | ||
210 | return; | ||
211 | } | ||
212 | ei_status.dmaing |= 0x01; | ||
213 | /* We should already be in page 0, but to be safe... */ | ||
214 | z_writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD); | ||
215 | |||
216 | z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); | ||
217 | |||
218 | /* Now the normal output. */ | ||
219 | z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO); | ||
220 | z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI); | ||
221 | z_writeb(0x00, nic_base + NE_EN0_RSARLO); | ||
222 | z_writeb(start_page, nic_base + NE_EN0_RSARHI); | ||
223 | |||
224 | z_writeb(E8390_RWRITE + E8390_START, nic_base + NE_CMD); | ||
225 | ptrs = (short *)buf; | ||
226 | for (cnt = 0; cnt < count >> 1; cnt++) | ||
227 | z_writew(*ptrs++, NE_BASE + NE_DATAPORT); | ||
228 | |||
229 | dma_start = jiffies; | ||
230 | |||
231 | while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0) | ||
232 | if (time_after(jiffies, dma_start + 2 * HZ / 100)) { | ||
233 | /* 20ms */ | ||
234 | netdev_err(dev, "timeout waiting for Tx RDC\n"); | ||
235 | zorro8390_reset_8390(dev); | ||
236 | __NS8390_init(dev, 1); | ||
237 | break; | ||
238 | } | ||
239 | |||
240 | z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr */ | ||
241 | ei_status.dmaing &= ~0x01; | ||
242 | } | ||
243 | |||
244 | static int zorro8390_open(struct net_device *dev) | ||
245 | { | ||
246 | __ei_open(dev); | ||
247 | return 0; | ||
248 | } | ||
249 | |||
250 | static int zorro8390_close(struct net_device *dev) | ||
251 | { | ||
252 | if (ei_debug > 1) | ||
253 | netdev_dbg(dev, "Shutting down ethercard\n"); | ||
254 | __ei_close(dev); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static void __devexit zorro8390_remove_one(struct zorro_dev *z) | ||
259 | { | ||
260 | struct net_device *dev = zorro_get_drvdata(z); | ||
261 | |||
262 | unregister_netdev(dev); | ||
263 | free_irq(IRQ_AMIGA_PORTS, dev); | ||
264 | release_mem_region(ZTWO_PADDR(dev->base_addr), NE_IO_EXTENT * 2); | ||
265 | free_netdev(dev); | ||
266 | } | ||
267 | |||
268 | static struct zorro_device_id zorro8390_zorro_tbl[] __devinitdata = { | ||
269 | { ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, }, | ||
270 | { ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, }, | ||
271 | { 0 } | ||
272 | }; | ||
273 | MODULE_DEVICE_TABLE(zorro, zorro8390_zorro_tbl); | ||
274 | |||
275 | static const struct net_device_ops zorro8390_netdev_ops = { | ||
276 | .ndo_open = zorro8390_open, | ||
277 | .ndo_stop = zorro8390_close, | ||
278 | .ndo_start_xmit = __ei_start_xmit, | ||
279 | .ndo_tx_timeout = __ei_tx_timeout, | ||
280 | .ndo_get_stats = __ei_get_stats, | ||
281 | .ndo_set_multicast_list = __ei_set_multicast_list, | ||
282 | .ndo_validate_addr = eth_validate_addr, | ||
283 | .ndo_set_mac_address = eth_mac_addr, | ||
284 | .ndo_change_mtu = eth_change_mtu, | ||
285 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
286 | .ndo_poll_controller = __ei_poll, | ||
287 | #endif | ||
288 | }; | ||
289 | |||
290 | static int __devinit zorro8390_init(struct net_device *dev, | ||
291 | unsigned long board, const char *name, | ||
292 | unsigned long ioaddr) | ||
293 | { | ||
294 | int i; | ||
295 | int err; | ||
296 | unsigned char SA_prom[32]; | ||
297 | int start_page, stop_page; | ||
298 | static u32 zorro8390_offsets[16] = { | ||
299 | 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, | ||
300 | 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, | ||
301 | }; | ||
302 | |||
303 | /* Reset card. Who knows what dain-bramaged state it was left in. */ | ||
304 | { | ||
305 | unsigned long reset_start_time = jiffies; | ||
306 | |||
307 | z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET); | ||
308 | |||
309 | while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0) | ||
310 | if (time_after(jiffies, | ||
311 | reset_start_time + 2 * HZ / 100)) { | ||
312 | netdev_warn(dev, "not found (no reset ack)\n"); | ||
313 | return -ENODEV; | ||
314 | } | ||
315 | |||
316 | z_writeb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */ | ||
317 | } | ||
318 | |||
319 | /* Read the 16 bytes of station address PROM. | ||
320 | * We must first initialize registers, | ||
321 | * similar to NS8390_init(eifdev, 0). | ||
322 | * We can't reliably read the SAPROM address without this. | ||
323 | * (I learned the hard way!). | ||
324 | */ | ||
325 | { | ||
326 | static const struct { | ||
327 | u32 value; | ||
328 | u32 offset; | ||
329 | } program_seq[] = { | ||
330 | {E8390_NODMA + E8390_PAGE0 + E8390_STOP, NE_CMD}, | ||
331 | /* Select page 0 */ | ||
332 | {0x48, NE_EN0_DCFG}, /* 0x48: Set byte-wide access */ | ||
333 | {0x00, NE_EN0_RCNTLO}, /* Clear the count regs */ | ||
334 | {0x00, NE_EN0_RCNTHI}, | ||
335 | {0x00, NE_EN0_IMR}, /* Mask completion irq */ | ||
336 | {0xFF, NE_EN0_ISR}, | ||
337 | {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */ | ||
338 | {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode */ | ||
339 | {32, NE_EN0_RCNTLO}, | ||
340 | {0x00, NE_EN0_RCNTHI}, | ||
341 | {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000 */ | ||
342 | {0x00, NE_EN0_RSARHI}, | ||
343 | {E8390_RREAD + E8390_START, NE_CMD}, | ||
344 | }; | ||
345 | for (i = 0; i < ARRAY_SIZE(program_seq); i++) | ||
346 | z_writeb(program_seq[i].value, | ||
347 | ioaddr + program_seq[i].offset); | ||
348 | } | ||
349 | for (i = 0; i < 16; i++) { | ||
350 | SA_prom[i] = z_readb(ioaddr + NE_DATAPORT); | ||
351 | (void)z_readb(ioaddr + NE_DATAPORT); | ||
352 | } | ||
353 | |||
354 | /* We must set the 8390 for word mode. */ | ||
355 | z_writeb(0x49, ioaddr + NE_EN0_DCFG); | ||
356 | start_page = NESM_START_PG; | ||
357 | stop_page = NESM_STOP_PG; | ||
358 | |||
359 | dev->base_addr = ioaddr; | ||
360 | dev->irq = IRQ_AMIGA_PORTS; | ||
361 | |||
362 | /* Install the Interrupt handler */ | ||
363 | i = request_irq(IRQ_AMIGA_PORTS, __ei_interrupt, | ||
364 | IRQF_SHARED, DRV_NAME, dev); | ||
365 | if (i) | ||
366 | return i; | ||
367 | |||
368 | for (i = 0; i < ETHER_ADDR_LEN; i++) | ||
369 | dev->dev_addr[i] = SA_prom[i]; | ||
370 | |||
371 | pr_debug("Found ethernet address: %pM\n", dev->dev_addr); | ||
372 | |||
373 | ei_status.name = name; | ||
374 | ei_status.tx_start_page = start_page; | ||
375 | ei_status.stop_page = stop_page; | ||
376 | ei_status.word16 = 1; | ||
377 | |||
378 | ei_status.rx_start_page = start_page + TX_PAGES; | ||
379 | |||
380 | ei_status.reset_8390 = zorro8390_reset_8390; | ||
381 | ei_status.block_input = zorro8390_block_input; | ||
382 | ei_status.block_output = zorro8390_block_output; | ||
383 | ei_status.get_8390_hdr = zorro8390_get_8390_hdr; | ||
384 | ei_status.reg_offset = zorro8390_offsets; | ||
385 | |||
386 | dev->netdev_ops = &zorro8390_netdev_ops; | ||
387 | __NS8390_init(dev, 0); | ||
388 | err = register_netdev(dev); | ||
389 | if (err) { | ||
390 | free_irq(IRQ_AMIGA_PORTS, dev); | ||
391 | return err; | ||
392 | } | ||
393 | |||
394 | netdev_info(dev, "%s at 0x%08lx, Ethernet Address %pM\n", | ||
395 | name, board, dev->dev_addr); | ||
396 | |||
397 | return 0; | ||
398 | } | ||
399 | |||
400 | static int __devinit zorro8390_init_one(struct zorro_dev *z, | ||
401 | const struct zorro_device_id *ent) | ||
402 | { | ||
403 | struct net_device *dev; | ||
404 | unsigned long board, ioaddr; | ||
405 | int err, i; | ||
406 | |||
407 | for (i = ARRAY_SIZE(cards) - 1; i >= 0; i--) | ||
408 | if (z->id == cards[i].id) | ||
409 | break; | ||
410 | if (i < 0) | ||
411 | return -ENODEV; | ||
412 | |||
413 | board = z->resource.start; | ||
414 | ioaddr = board + cards[i].offset; | ||
415 | dev = ____alloc_ei_netdev(0); | ||
416 | if (!dev) | ||
417 | return -ENOMEM; | ||
418 | if (!request_mem_region(ioaddr, NE_IO_EXTENT * 2, DRV_NAME)) { | ||
419 | free_netdev(dev); | ||
420 | return -EBUSY; | ||
421 | } | ||
422 | err = zorro8390_init(dev, board, cards[i].name, ZTWO_VADDR(ioaddr)); | ||
423 | if (err) { | ||
424 | release_mem_region(ioaddr, NE_IO_EXTENT * 2); | ||
425 | free_netdev(dev); | ||
426 | return err; | ||
427 | } | ||
428 | zorro_set_drvdata(z, dev); | ||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static struct zorro_driver zorro8390_driver = { | ||
433 | .name = "zorro8390", | ||
434 | .id_table = zorro8390_zorro_tbl, | ||
435 | .probe = zorro8390_init_one, | ||
436 | .remove = __devexit_p(zorro8390_remove_one), | ||
437 | }; | ||
438 | |||
439 | static int __init zorro8390_init_module(void) | ||
440 | { | ||
441 | return zorro_register_driver(&zorro8390_driver); | ||
442 | } | ||
443 | |||
444 | static void __exit zorro8390_cleanup_module(void) | ||
445 | { | ||
446 | zorro_unregister_driver(&zorro8390_driver); | ||
447 | } | ||
448 | |||
449 | module_init(zorro8390_init_module); | ||
450 | module_exit(zorro8390_cleanup_module); | ||
451 | |||
452 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig index 5e62efd58172..56ed5ec9a503 100644 --- a/drivers/net/ethernet/Kconfig +++ b/drivers/net/ethernet/Kconfig | |||
@@ -12,6 +12,7 @@ menuconfig ETHERNET | |||
12 | if ETHERNET | 12 | if ETHERNET |
13 | 13 | ||
14 | source "drivers/net/ethernet/3com/Kconfig" | 14 | source "drivers/net/ethernet/3com/Kconfig" |
15 | source "drivers/net/ethernet/8390/Kconfig" | ||
15 | source "drivers/net/ethernet/amd/Kconfig" | 16 | source "drivers/net/ethernet/amd/Kconfig" |
16 | 17 | ||
17 | endif # ETHERNET | 18 | endif # ETHERNET |
diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile index 1bc2ac25bab0..fc82588fb2f4 100644 --- a/drivers/net/ethernet/Makefile +++ b/drivers/net/ethernet/Makefile | |||
@@ -3,4 +3,5 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_NET_VENDOR_3COM) += 3com/ | 5 | obj-$(CONFIG_NET_VENDOR_3COM) += 3com/ |
6 | obj-$(CONFIG_NET_VENDOR_8390) += 8390/ | ||
6 | obj-$(CONFIG_NET_VENDOR_AMD) += amd/ | 7 | obj-$(CONFIG_NET_VENDOR_AMD) += amd/ |