1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24static 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
29#include <linux/kernel.h>
30#include <linux/sched.h>
31#include <linux/errno.h>
32#include <linux/string.h>
33#include <linux/netdevice.h>
34#include <linux/etherdevice.h>
35#include <linux/init.h>
36
37#include <asm/system.h>
38#include <asm/io.h>
39#include <asm/irq.h>
40
41#include "8390.h"
42
43
44#define AC_NIC_BASE 0x00
45#define AC_SA_PROM 0x16
46#define AC_ADDR0 0x00
47#define AC_ADDR1 0x40
48#define AC_ADDR2 0x90
49#define AC_ID_PORT 0xC80
50#define AC_EISA_ID 0x0110d305
51#define AC_RESET_PORT 0xC84
52#define AC_RESET 0x00
53#define AC_ENABLE 0x01
54#define AC_CONFIG 0xC90
55
56#define AC_IO_EXTENT 0x20
57
58
59
60
61
62
63
64
65
66static unsigned char config2irqmap[8] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
67static int addrmap[8] =
68{0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000, 0xD0000, 0 };
69static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"};
70
71#define config2irq(configval) config2irqmap[((configval) >> 3) & 7]
72#define config2mem(configval) addrmap[(configval) & 7]
73#define config2name(configval) port_name[((configval) >> 6) & 3]
74
75
76#define AC_START_PG 0x00
77#define AC_STOP_PG 0x80
78
79int ac3200_probe(struct net_device *dev);
80static int ac_probe1(int ioaddr, struct net_device *dev);
81
82static int ac_open(struct net_device *dev);
83static void ac_reset_8390(struct net_device *dev);
84static void ac_block_input(struct net_device *dev, int count,
85 struct sk_buff *skb, int ring_offset);
86static void ac_block_output(struct net_device *dev, const int count,
87 const unsigned char *buf, const int start_page);
88static void ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
89 int ring_page);
90
91static int ac_close_card(struct net_device *dev);
92
93
94
95
96
97
98
99
100int __init ac3200_probe(struct net_device *dev)
101{
102 unsigned short ioaddr = dev->base_addr;
103
104 SET_MODULE_OWNER(dev);
105
106 if (ioaddr > 0x1ff)
107 return ac_probe1(ioaddr, dev);
108 else if (ioaddr > 0)
109 return -ENXIO;
110
111 if ( ! EISA_bus)
112 return -ENXIO;
113
114 for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000)
115 if (ac_probe1(ioaddr, dev) == 0)
116 return 0;
117
118 return -ENODEV;
119}
120
121static int __init ac_probe1(int ioaddr, struct net_device *dev)
122{
123 int i, retval;
124
125 if (!request_region(ioaddr, AC_IO_EXTENT, dev->name))
126 return -EBUSY;
127
128 if (inb_p(ioaddr + AC_ID_PORT) == 0xff) {
129 retval = -ENODEV;
130 goto out;
131 }
132
133 if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
134 retval = -ENODEV;
135 goto out;
136 }
137
138#ifndef final_version
139 printk(KERN_DEBUG "AC3200 ethercard configuration register is %#02x,"
140 " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG),
141 inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1),
142 inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3));
143#endif
144
145 printk("AC3200 in EISA slot %d, node", ioaddr/0x1000);
146 for(i = 0; i < 6; i++)
147 printk(" %02x", dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i));
148
149#if 0
150
151 if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0
152 || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1
153 || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) {
154 printk(", not found (invalid prefix).\n");
155 retval = -ENODEV;
156 goto out;
157 }
158#endif
159
160
161 if (ethdev_init(dev)) {
162 printk (", unable to allocate memory for dev->priv.\n");
163 retval = -ENOMEM;
164 goto out;
165 }
166
167
168 if (dev->irq == 0) {
169 dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
170 printk(", using");
171 } else {
172 dev->irq = irq_cannonicalize(dev->irq);
173 printk(", assigning");
174 }
175
176 retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
177 if (retval) {
178 printk (" nothing! Unable to get IRQ %d.\n", dev->irq);
179 goto out1;
180 }
181
182 printk(" IRQ %d, %s port\n", dev->irq, port_name[dev->if_port]);
183
184 dev->base_addr = ioaddr;
185
186#ifdef notyet
187 if (dev->mem_start) {
188 for (i = 0; i < 7; i++)
189 if (addrmap[i] == dev->mem_start)
190 break;
191 if (i >= 7)
192 i = 0;
193 outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG);
194 }
195#endif
196
197 dev->if_port = inb(ioaddr + AC_CONFIG) >> 6;
198 dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG));
199
200 printk("%s: AC3200 at %#3x with %dkB memory at physical address %#lx.\n",
201 dev->name, ioaddr, AC_STOP_PG/4, dev->mem_start);
202
203
204
205
206
207 if (dev->mem_start > 1024*1024) {
208 if (dev->mem_start < virt_to_phys(high_memory)) {
209 printk(KERN_CRIT "ac3200.c: Card RAM overlaps with normal memory!!!\n");
210 printk(KERN_CRIT "ac3200.c: Use EISA SCU to set card memory below 1MB,\n");
211 printk(KERN_CRIT "ac3200.c: or to an address above 0x%lx.\n", virt_to_phys(high_memory));
212 printk(KERN_CRIT "ac3200.c: Driver NOT installed.\n");
213 retval = -EINVAL;
214 goto out2;
215 }
216 dev->mem_start = (unsigned long)ioremap(dev->mem_start, AC_STOP_PG*0x100);
217 if (dev->mem_start == 0) {
218 printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n");
219 printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n");
220 printk(KERN_ERR "ac3200.c: Driver NOT installed.\n");
221 retval = -EINVAL;
222 goto out2;
223 }
224 ei_status.reg0 = 1;
225 printk("ac3200.c: remapped %dkB card memory to virtual address %#lx\n",
226 AC_STOP_PG/4, dev->mem_start);
227 }
228
229 ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
230 dev->mem_end = ei_status.rmem_end = dev->mem_start
231 + (AC_STOP_PG - AC_START_PG)*256;
232
233 ei_status.name = "AC3200";
234 ei_status.tx_start_page = AC_START_PG;
235 ei_status.rx_start_page = AC_START_PG + TX_PAGES;
236 ei_status.stop_page = AC_STOP_PG;
237 ei_status.word16 = 1;
238
239 if (ei_debug > 0)
240 printk(version);
241
242 ei_status.reset_8390 = &ac_reset_8390;
243 ei_status.block_input = &ac_block_input;
244 ei_status.block_output = &ac_block_output;
245 ei_status.get_8390_hdr = &ac_get_8390_hdr;
246
247 dev->open = &ac_open;
248 dev->stop = &ac_close_card;
249 NS8390_init(dev, 0);
250 return 0;
251out2:
252 free_irq(dev->irq, dev);
253out1:
254 kfree(dev->priv);
255 dev->priv = NULL;
256out:
257 release_region(ioaddr, AC_IO_EXTENT);
258 return retval;
259}
260
261static int ac_open(struct net_device *dev)
262{
263#ifdef notyet
264
265 int ioaddr = dev->base_addr;
266#endif
267
268 ei_open(dev);
269 return 0;
270}
271
272static void ac_reset_8390(struct net_device *dev)
273{
274 ushort ioaddr = dev->base_addr;
275
276 outb(AC_RESET, ioaddr + AC_RESET_PORT);
277 if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies);
278
279 ei_status.txing = 0;
280 outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
281 if (ei_debug > 1) printk("reset done\n");
282
283 return;
284}
285
286
287
288
289
290static void
291ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
292{
293 unsigned long hdr_start = dev->mem_start + ((ring_page - AC_START_PG)<<8);
294 isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
295}
296
297
298
299
300static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb,
301 int ring_offset)
302{
303 unsigned long xfer_start = dev->mem_start + ring_offset - (AC_START_PG<<8);
304
305 if (xfer_start + count > ei_status.rmem_end) {
306
307 int semi_count = ei_status.rmem_end - xfer_start;
308 isa_memcpy_fromio(skb->data, xfer_start, semi_count);
309 count -= semi_count;
310 isa_memcpy_fromio(skb->data + semi_count, ei_status.rmem_start, count);
311 } else {
312
313 isa_eth_io_copy_and_sum(skb, xfer_start, count, 0);
314 }
315}
316
317static void ac_block_output(struct net_device *dev, int count,
318 const unsigned char *buf, int start_page)
319{
320 unsigned long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8);
321
322 isa_memcpy_toio(shmem, buf, count);
323}
324
325static int ac_close_card(struct net_device *dev)
326{
327 if (ei_debug > 1)
328 printk("%s: Shutting down ethercard.\n", dev->name);
329
330#ifdef notyet
331
332 outb(0x00, ioaddr + 6);
333 free_irq(dev->irq, dev);
334#endif
335
336 ei_close(dev);
337 return 0;
338}
339
340#ifdef MODULE
341#define MAX_AC32_CARDS 4
342static struct net_device dev_ac32[MAX_AC32_CARDS];
343static int io[MAX_AC32_CARDS];
344static int irq[MAX_AC32_CARDS];
345static int mem[MAX_AC32_CARDS];
346MODULE_PARM(io, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
347MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
348MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
349MODULE_PARM_DESC(io, "I/O base adress(es)");
350MODULE_PARM_DESC(irq, "IRQ number(s)");
351MODULE_PARM_DESC(mem, "Memory base address(es)");
352MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver");
353MODULE_LICENSE("GPL");
354
355int
356init_module(void)
357{
358 int this_dev, found = 0;
359
360 for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
361 struct net_device *dev = &dev_ac32[this_dev];
362 dev->irq = irq[this_dev];
363 dev->base_addr = io[this_dev];
364 dev->mem_start = mem[this_dev];
365 dev->init = ac3200_probe;
366
367 if (io[this_dev] == 0 && this_dev != 0) break;
368 if (register_netdev(dev) != 0) {
369 printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
370 if (found != 0) {
371 return 0;
372 }
373 return -ENXIO;
374 }
375 found++;
376 }
377 return 0;
378}
379
380void
381cleanup_module(void)
382{
383 int this_dev;
384
385 for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
386 struct net_device *dev = &dev_ac32[this_dev];
387 if (dev->priv != NULL) {
388
389 free_irq(dev->irq, dev);
390 release_region(dev->base_addr, AC_IO_EXTENT);
391 if (ei_status.reg0)
392 iounmap((void *)dev->mem_start);
393 unregister_netdev(dev);
394 kfree(dev->priv);
395 dev->priv = NULL;
396 }
397 }
398}
399#endif
400
401
402
403
404
405
406
407
408
409
410