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
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/* Offsets from the base address. */
44#define AC_NIC_BASE	0x00
45#define AC_SA_PROM	0x16			/* The station address PROM. */
46#define AC_ADDR0	0x00			/* Prefix station address values. */
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	/* The configuration port. */
55
56#define AC_IO_EXTENT 0x20
57                                /* Actually accessed is:
58								 * AC_NIC_BASE (0-15)
59								 * AC_SA_PROM (0-5)
60								 * AC_ID_PORT (0-3)
61								 * AC_RESET_PORT
62								 * AC_CONFIG
63								 */
64
65/* Decoding of the configuration register. */
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/* First and last 8390 pages. */
76#define AC_START_PG		0x00	/* First page of 8390 TX buffer */
77#define AC_STOP_PG		0x80	/* Last page +1 of the 8390 RX ring */
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/*	Probe for the AC3200.
95
96	The AC3200 can be identified by either the EISA configuration registers,
97	or the unique value in the station address PROM.
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)		/* Check a single specified location. */
107		return ac_probe1(ioaddr, dev);
108	else if (ioaddr > 0)		/* Don't probe at all. */
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
150	/* Allocate dev->priv and fill in 8390 specific dev fields. */
151	if (ethdev_init(dev)) {
152		printk (", unable to allocate memory for dev->priv.\n");
153		retval = -ENOMEM;
154		goto out;
155	}
156
157	/* Assign and allocate the interrupt now. */
158	if (dev->irq == 0) {
159		dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
160		printk(", using");
161	} else {
162		dev->irq = irq_cannonicalize(dev->irq);
163		printk(", assigning");
164	}
165
166	retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev);
167	if (retval) {
168		printk (" nothing! Unable to get IRQ %d.\n", dev->irq);
169		goto out1;
170	}
171
172	printk(" IRQ %d, %s port\n", dev->irq, port_name[dev->if_port]);
173
174	dev->base_addr = ioaddr;
175
176#ifdef notyet
177	if (dev->mem_start)	{		/* Override the value from the board. */
178		for (i = 0; i < 7; i++)
179			if (addrmap[i] == dev->mem_start)
180				break;
181		if (i >= 7)
182			i = 0;
183		outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG);
184	}
185#endif
186
187	dev->if_port = inb(ioaddr + AC_CONFIG) >> 6;
188	dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG));
189
190	printk("%s: AC3200 at %#3x with %dkB memory at physical address %#lx.\n",
191			dev->name, ioaddr, AC_STOP_PG/4, dev->mem_start);
192
193	/*
194	 *  BEWARE!! Some dain-bramaged EISA SCUs will allow you to put
195	 *  the card mem within the region covered by `normal' RAM  !!!
196	 */
197	if (dev->mem_start > 1024*1024) {	/* phys addr > 1MB */
198		if (dev->mem_start < virt_to_bus(high_memory)) {
199			printk(KERN_CRIT "ac3200.c: Card RAM overlaps with normal memory!!!\n");
200			printk(KERN_CRIT "ac3200.c: Use EISA SCU to set card memory below 1MB,\n");
201			printk(KERN_CRIT "ac3200.c: or to an address above 0x%lx.\n", virt_to_bus(high_memory));
202			printk(KERN_CRIT "ac3200.c: Driver NOT installed.\n");
203			retval = -EINVAL;
204			goto out2;
205		}
206		dev->mem_start = (unsigned long)ioremap(dev->mem_start, AC_STOP_PG*0x100);
207		if (dev->mem_start == 0) {
208			printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n");
209			printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n");
210			printk(KERN_ERR "ac3200.c: Driver NOT installed.\n");
211			retval = -EINVAL;
212			goto out2;
213		}
214		ei_status.reg0 = 1;	/* Use as remap flag */
215		printk("ac3200.c: remapped %dkB card memory to virtual address %#lx\n",
216				AC_STOP_PG/4, dev->mem_start);
217	}
218
219	dev->rmem_start = dev->mem_start + TX_PAGES*256;
220	dev->mem_end = dev->rmem_end = dev->mem_start
221		+ (AC_STOP_PG - AC_START_PG)*256;
222
223	ei_status.name = "AC3200";
224	ei_status.tx_start_page = AC_START_PG;
225	ei_status.rx_start_page = AC_START_PG + TX_PAGES;
226	ei_status.stop_page = AC_STOP_PG;
227	ei_status.word16 = 1;
228
229	if (ei_debug > 0)
230		printk(version);
231
232	ei_status.reset_8390 = &ac_reset_8390;
233	ei_status.block_input = &ac_block_input;
234	ei_status.block_output = &ac_block_output;
235	ei_status.get_8390_hdr = &ac_get_8390_hdr;
236
237	dev->open = &ac_open;
238	dev->stop = &ac_close_card;
239	NS8390_init(dev, 0);
240	return 0;
241out2:
242	free_irq(dev->irq, dev);
243out1:
244	kfree(dev->priv);
245	dev->priv = NULL;
246out:
247	release_region(ioaddr, AC_IO_EXTENT);
248	return retval;
249}
250
251static int ac_open(struct net_device *dev)
252{
253#ifdef notyet
254	/* Someday we may enable the IRQ and shared memory here. */
255	int ioaddr = dev->base_addr;
256#endif
257
258	ei_open(dev);
259	return 0;
260}
261
262static void ac_reset_8390(struct net_device *dev)
263{
264	ushort ioaddr = dev->base_addr;
265
266	outb(AC_RESET, ioaddr + AC_RESET_PORT);
267	if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies);
268
269	ei_status.txing = 0;
270	outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
271	if (ei_debug > 1) printk("reset done\n");
272
273	return;
274}
275
276/* Grab the 8390 specific header. Similar to the block_input routine, but
277   we don't need to be concerned with ring wrap as the header will be at
278   the start of a page, so we optimize accordingly. */
279
280static void
281ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
282{
283	unsigned long hdr_start = dev->mem_start + ((ring_page - AC_START_PG)<<8);
284	isa_memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
285}
286
287/*  Block input and output are easy on shared memory ethercards, the only
288	complication is when the ring buffer wraps. */
289
290static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb,
291						  int ring_offset)
292{
293	unsigned long xfer_start = dev->mem_start + ring_offset - (AC_START_PG<<8);
294
295	if (xfer_start + count > dev->rmem_end) {
296		/* We must wrap the input move. */
297		int semi_count = dev->rmem_end - xfer_start;
298		isa_memcpy_fromio(skb->data, xfer_start, semi_count);
299		count -= semi_count;
300		isa_memcpy_fromio(skb->data + semi_count, dev->rmem_start, count);
301	} else {
302		/* Packet is in one chunk -- we can copy + cksum. */
303		isa_eth_io_copy_and_sum(skb, xfer_start, count, 0);
304	}
305}
306
307static void ac_block_output(struct net_device *dev, int count,
308							const unsigned char *buf, int start_page)
309{
310	unsigned long shmem = dev->mem_start + ((start_page - AC_START_PG)<<8);
311
312	isa_memcpy_toio(shmem, buf, count);
313}
314
315static int ac_close_card(struct net_device *dev)
316{
317	if (ei_debug > 1)
318		printk("%s: Shutting down ethercard.\n", dev->name);
319
320#ifdef notyet
321	/* We should someday disable shared memory and interrupts. */
322	outb(0x00, ioaddr + 6);	/* Disable interrupts. */
323	free_irq(dev->irq, dev);
324#endif
325
326	ei_close(dev);
327	return 0;
328}
329
330#ifdef MODULE
331#define MAX_AC32_CARDS	4	/* Max number of AC32 cards per module */
332static struct net_device dev_ac32[MAX_AC32_CARDS];
333static int io[MAX_AC32_CARDS];
334static int irq[MAX_AC32_CARDS];
335static int mem[MAX_AC32_CARDS];
336MODULE_PARM(io, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
337MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
338MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_AC32_CARDS) "i");
339MODULE_PARM_DESC(io, "I/O base adress(es)");
340MODULE_PARM_DESC(irq, "IRQ number(s)");
341MODULE_PARM_DESC(mem, "Memory base address(es)");
342MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver");
343MODULE_LICENSE("GPL");
344
345int
346init_module(void)
347{
348	int this_dev, found = 0;
349
350	for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
351		struct net_device *dev = &dev_ac32[this_dev];
352		dev->irq = irq[this_dev];
353		dev->base_addr = io[this_dev];
354		dev->mem_start = mem[this_dev];		/* Currently ignored by driver */
355		dev->init = ac3200_probe;
356		/* Default is to only install one card. */
357		if (io[this_dev] == 0 && this_dev != 0) break;
358		if (register_netdev(dev) != 0) {
359			printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
360			if (found != 0) {	/* Got at least one. */
361				return 0;
362			}
363			return -ENXIO;
364		}
365		found++;
366	}
367	return 0;
368}
369
370void
371cleanup_module(void)
372{
373	int this_dev;
374
375	for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
376		struct net_device *dev = &dev_ac32[this_dev];
377		if (dev->priv != NULL) {
378			/* Someday free_irq may be in ac_close_card() */
379			free_irq(dev->irq, dev);
380			release_region(dev->base_addr, AC_IO_EXTENT);
381			if (ei_status.reg0)
382				iounmap((void *)dev->mem_start);
383			unregister_netdev(dev);
384			kfree(dev->priv);
385			dev->priv = NULL;
386		}
387	}
388}
389#endif /* MODULE */
390
391
392/*
393 * Local variables:
394 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c ac3200.c"
395 *  version-control: t
396 *  kept-new-versions: 5
397 *  tab-width: 4
398 * End:
399 */
400