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 Public License as modified by SRC,
7 incorporated herein by reference.
8
9 The author may be reached as becker@cesdis.gsfc.nasa.gov, or
10 C/O Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
11
12 This is driver for the Ansel Communications Model 3200 EISA Ethernet LAN
13 Adapter. The programming information is from the users manual, as related
14 by glee@ardnassak.math.clemson.edu.
15
16 Changelog:
17
18 Paul Gortmaker 05/98 : add support for shared mem above 1MB.
19
20 */
21
22 static const char *version =
23 "ac3200.c:v1.01 7/1/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
24
25 #include <linux/module.h>
26
27 #include <linux/kernel.h>
28 #include <linux/sched.h>
29 #include <linux/errno.h>
30 #include <linux/string.h>
31 #include <linux/netdevice.h>
32 #include <linux/etherdevice.h>
33 #include <linux/init.h>
34
35 #include <asm/system.h>
36 #include <asm/io.h>
37 #include <asm/irq.h>
38
39 #include "8390.h"
40
41 /* Offsets from the base address. */
42 #define AC_NIC_BASE 0x00
43 #define AC_SA_PROM 0x16 /* The station address PROM. */
44 #define AC_ADDR0 0x00 /* Prefix station address values. */
45 #define AC_ADDR1 0x40
46 #define AC_ADDR2 0x90
47 #define AC_ID_PORT 0xC80
48 #define AC_EISA_ID 0x0110d305
49 #define AC_RESET_PORT 0xC84
50 #define AC_RESET 0x00
51 #define AC_ENABLE 0x01
52 #define AC_CONFIG 0xC90 /* The configuration port. */
53
54 #define AC_IO_EXTENT 0x20
55 /* Actually accessed is:
56 * AC_NIC_BASE (0-15)
57 * AC_SA_PROM (0-5)
58 * AC_ID_PORT (0-3)
59 * AC_RESET_PORT
60 * AC_CONFIG
61 */
62
63 /* Decoding of the configuration register. */
64 static unsigned char config2irqmap[8] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
65 static int addrmap[8] =
66 {0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000, 0xD0000, 0 };
67 static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"};
68
69 #define config2irq(configval) config2irqmap[((configval) >> 3) & 7]
70 #define config2mem(configval) addrmap[(configval) & 7]
71 #define config2name(configval) port_name[((configval) >> 6) & 3]
72
73 /* First and last 8390 pages. */
74 #define AC_START_PG 0x00 /* First page of 8390 TX buffer */
75 #define AC_STOP_PG 0x80 /* Last page +1 of the 8390 RX ring */
76
77 int ac3200_probe(struct net_device *dev);
78 static int ac_probe1(int ioaddr, struct net_device *dev);
79
80 static int ac_open(struct net_device *dev);
81 static void ac_reset_8390(struct net_device *dev);
82 static void ac_block_input(struct net_device *dev, int count,
83 struct sk_buff *skb, int ring_offset);
84 static void ac_block_output(struct net_device *dev, const int count,
85 const unsigned char *buf, const int start_page);
86 static void ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
87 int ring_page);
88
89 static int ac_close_card(struct net_device *dev);
90
91
92 /* Probe for the AC3200.
93
94 The AC3200 can be identified by either the EISA configuration registers,
95 or the unique value in the station address PROM.
96 */
97
98 int __init ac3200_probe(struct net_device *dev)
99 {
100 unsigned short ioaddr = dev->base_addr;
101
102 SET_MODULE_OWNER(dev);
103
104 if (ioaddr > 0x1ff) /* Check a single specified location. */
105 return ac_probe1(ioaddr, dev);
106 else if (ioaddr > 0) /* Don't probe at all. */
107 return -ENXIO;
108
109 if ( ! EISA_bus)
110 return -ENXIO;
111
112 for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000)
113 if (ac_probe1(ioaddr, dev) == 0)
114 return 0;
115
116 return -ENODEV;
117 }
118
119 static int __init ac_probe1(int ioaddr, struct net_device *dev)
120 {
121 int i, retval;
122
123 if (!request_region(ioaddr, AC_IO_EXTENT, dev->name))
124 return -EBUSY;
125
126 if (inb_p(ioaddr + AC_ID_PORT) == 0xff) {
127 retval = -ENODEV;
128 goto out;
129 }
130
131 if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
132 retval = -ENODEV;
133 goto out;
134 }
135
136 #ifndef final_version
137 printk(KERN_DEBUG "AC3200 ethercard configuration register is %#02x,"
138 " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG),
139 inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1),
140 inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3));
141 #endif
142
143 printk("AC3200 in EISA slot %d, node", ioaddr/0x1000);
144 for(i = 0; i < 6; i++)
145 printk(" %02x", dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i));
146
147 #if 0
148 /* Check the vendor ID/prefix. Redundant after checking the EISA ID */
149 if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0
150 || inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1
151 || inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) {
152 printk(", not found (invalid prefix).\n");
153 retval = -ENODEV;
154 goto out;
155 }
156 #endif
157
158 /* Allocate dev->priv and fill in 8390 specific dev fields. */
159 if (ethdev_init(dev)) {
160 printk (", unable to allocate memory for dev->priv.\n");
161 retval = -ENOMEM;
162 goto out;
163 }
164
165 /* Assign and allocate the interrupt now. */
166 if (dev->irq == 0) {
167 dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
168 printk(", using");
169 } else {
170 dev->irq = irq_cannonicalize(dev->irq);
171 printk(", assigning");
172 }
173
174 retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
175 if (retval) {
176 printk (" nothing! Unable to get IRQ %d.\n", dev->irq);
177 goto out1;
178 }
179
180 printk(" IRQ %d, %s port\n", dev->irq, port_name[dev->if_port]);
181
182 dev->base_addr = ioaddr;
183
184 #ifdef notyet
185 if (dev->mem_start) { /* Override the value from the board. */
186 for (i = 0; i < 7; i++)
187 if (addrmap[i] == dev->mem_start)
188 break;
189 if (i >= 7)
190 i = 0;
191 outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG);
192 }
193 #endif
194
195 dev->if_port = inb(ioaddr + AC_CONFIG) >> 6;
196 dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG));
197
198 printk("%s: AC3200 at %#3x with %dkB memory at physical address %#lx.\n",
199 dev->name, ioaddr, AC_STOP_PG/4, dev->mem_start);
200
201 /*
202 * BEWARE!! Some dain-bramaged EISA SCUs will allow you to put
203 * the card mem within the region covered by `normal' RAM !!!
204 */
205 if (dev->mem_start > 1024*1024) { /* phys addr > 1MB */
206 if (dev->mem_start < virt_to_bus(high_memory)) {
207 printk(KERN_CRIT "ac3200.c: Card RAM overlaps with normal memory!!!\n");
208 printk(KERN_CRIT "ac3200.c: Use EISA SCU to set card memory below 1MB,\n");
209 printk(KERN_CRIT "ac3200.c: or to an address above 0x%lx.\n", virt_to_bus(high_memory));
210 printk(KERN_CRIT "ac3200.c: Driver NOT installed.\n");
211 retval = -EINVAL;
212 goto out2;
213 }
214 dev->mem_start = (unsigned long)ioremap(dev->mem_start, AC_STOP_PG*0x100);
215 if (dev->mem_start == 0) {
216 printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n");
217 printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n");
218 printk(KERN_ERR "ac3200.c: Driver NOT installed.\n");
219 retval = -EINVAL;
220 goto out2;
221 }
222 ei_status.reg0 = 1; /* Use as remap flag */
223 printk("ac3200.c: remapped %dkB card memory to virtual address %#lx\n",
224 AC_STOP_PG/4, dev->mem_start);
225 }
226
227 dev->rmem_start = dev->mem_start + TX_PAGES*256;
228 dev->mem_end = dev->rmem_end = dev->mem_start
229 + (AC_STOP_PG - AC_START_PG)*256;
230
231 ei_status.name = "AC3200";
232 ei_status.tx_start_page = AC_START_PG;
233 ei_status.rx_start_page = AC_START_PG + TX_PAGES;
234 ei_status.stop_page = AC_STOP_PG;
235 ei_status.word16 = 1;
236
237 if (ei_debug > 0)
238 printk(version);
239
240 ei_status.reset_8390 = &ac_reset_8390;
241 ei_status.block_input = &ac_block_input;
242 ei_status.block_output = &ac_block_output;
243 ei_status.get_8390_hdr = &ac_get_8390_hdr;
244
245 dev->open = &ac_open;
246 dev->stop = &ac_close_card;
247 NS8390_init(dev, 0);
248 return 0;
249 out2:
250 free_irq(dev->irq, dev);
251 out1:
252 kfree(dev->priv);
253 dev->priv = NULL;
254 out:
255 release_region(ioaddr, AC_IO_EXTENT);
256 return retval;
257 }
258
259 static int ac_open(struct net_device *dev)
260 {
261 #ifdef notyet
262 /* Someday we may enable the IRQ and shared memory here. */
263 int ioaddr = dev->base_addr;
264 #endif
265
266 ei_open(dev);
267 return 0;
268 }
269
270 static void ac_reset_8390(struct net_device *dev)
271 {
272 ushort ioaddr = dev->base_addr;
273
274 outb(AC_RESET, ioaddr + AC_RESET_PORT);
275 if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies);
276
277 ei_status.txing = 0;
278 outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
279 if (ei_debug > 1) printk("reset done\n");
280
281 return;
282 }
283
284 /* Grab the 8390 specific header. Similar to the block_input routine, but
285 we don't need to be concerned with ring wrap as the header will be at
286 the start of a page, so we optimize accordingly. */
287
288 static void
289 ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
290 {
291 unsigned long hdr_start = dev->mem_start + ((ring_page - AC_START_PG)<<8);
292 isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
293 }
294
295 /* Block input and output are easy on shared memory ethercards, the only
296 complication is when the ring buffer wraps. */
297
298 static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb,
299 int ring_offset)
300 {
301 unsigned long xfer_start = dev->mem_start + ring_offset - (AC_START_PG<<8);
302
303 if (xfer_start + count > dev->rmem_end) {
304 /* We must wrap the input move. */
305 int semi_count = dev->rmem_end - xfer_start;
306 isa_memcpy_fromio(skb->data, xfer_start, semi_count);
307 count -= semi_count;
308 isa_memcpy_fromio(skb->data + semi_count, dev->rmem_start, count);
309 } else {
310 /* Packet is in one chunk -- we can copy + cksum. */
311 isa_eth_io_copy_and_sum(skb, xfer_start, count, 0);
312 }
313 }
314
315 static void ac_block_output(struct net_device *dev, int count,
316 const unsigned char *buf, int start_page)
317 {
318 unsigned long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8);
319
320 isa_memcpy_toio(shmem, buf, count);
321 }
322
323 static int ac_close_card(struct net_device *dev)
324 {
325 if (ei_debug > 1)
326 printk("%s: Shutting down ethercard.\n", dev->name);
327
328 #ifdef notyet
329 /* We should someday disable shared memory and interrupts. */
330 outb(0x00, ioaddr + 6); /* Disable interrupts. */
331 free_irq(dev->irq, dev);
332 #endif
333
334 ei_close(dev);
335 return 0;
336 }
337
338 #ifdef MODULE
339 #define MAX_AC32_CARDS 4 /* Max number of AC32 cards per module */
340 static struct net_device dev_ac32[MAX_AC32_CARDS];
341 static int io[MAX_AC32_CARDS];
342 static int irq[MAX_AC32_CARDS];
343 static int mem[MAX_AC32_CARDS];
344 MODULE_PARM(io, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
345 MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
346 MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
347
348 int
349 init_module(void)
350 {
351 int this_dev, found = 0;
352
353 for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
354 struct net_device *dev = &dev_ac32[this_dev];
355 dev->irq = irq[this_dev];
356 dev->base_addr = io[this_dev];
357 dev->mem_start = mem[this_dev]; /* Currently ignored by driver */
358 dev->init = ac3200_probe;
359 /* Default is to only install one card. */
360 if (io[this_dev] == 0 && this_dev != 0) break;
361 if (register_netdev(dev) != 0) {
362 printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
363 if (found != 0) { /* Got at least one. */
364 return 0;
365 }
366 return -ENXIO;
367 }
368 found++;
369 }
370 return 0;
371 }
372
373 void
374 cleanup_module(void)
375 {
376 int this_dev;
377
378 for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
379 struct net_device *dev = &dev_ac32[this_dev];
380 if (dev->priv != NULL) {
381 /* Someday free_irq may be in ac_close_card() */
382 free_irq(dev->irq, dev);
383 release_region(dev->base_addr, AC_IO_EXTENT);
384 if (ei_status.reg0)
385 iounmap((void *)dev->mem_start);
386 unregister_netdev(dev);
387 kfree(dev->priv);
388 dev->priv = NULL;
389 }
390 }
391 }
392 #endif /* MODULE */
393
394 /*
395 * Local variables:
396 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c ac3200.c"
397 * version-control: t
398 * kept-new-versions: 5
399 * tab-width: 4
400 * End:
401 */
402
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.