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