Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.4.
  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#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. */
 68static unsigned char config2irqmap[8] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
 69static int addrmap[8] =
 70{0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000,  0xD0000, 0 };
 71static 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
 81static int ac_probe1(int ioaddr, struct net_device *dev);
 82
 83static int ac_open(struct net_device *dev);
 84static void ac_reset_8390(struct net_device *dev);
 85static void ac_block_input(struct net_device *dev, int count,
 86					struct sk_buff *skb, int ring_offset);
 87static void ac_block_output(struct net_device *dev, const int count,
 88							const unsigned char *buf, const int start_page);
 89static void ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
 90					int ring_page);
 91
 92static 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
101static 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
126struct 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;
141out:
142	free_netdev(dev);
143	return ERR_PTR(err);
144}
145#endif
146
147static 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
163static 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;
280out2:
281	if (ei_status.reg0)
282		iounmap(ei_status.mem);
283out1:
284	free_irq(dev->irq, dev);
285out:
286	release_region(ioaddr, AC_IO_EXTENT);
287	return retval;
288}
289
290static 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
301static 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
317static void
318ac_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
327static 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
344static 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
352static 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 */
369static struct net_device *dev_ac32[MAX_AC32_CARDS];
370static int io[MAX_AC32_CARDS];
371static int irq[MAX_AC32_CARDS];
372static int mem[MAX_AC32_CARDS];
373module_param_array(io, int, NULL, 0);
374module_param_array(irq, int, NULL, 0);
375module_param_array(mem, int, NULL, 0);
376MODULE_PARM_DESC(io, "I/O base address(es)");
377MODULE_PARM_DESC(irq, "IRQ number(s)");
378MODULE_PARM_DESC(mem, "Memory base address(es)");
379MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver");
380MODULE_LICENSE("GPL");
381
382static 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
409static 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
417static 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}
430module_init(ac3200_module_init);
431module_exit(ac3200_module_exit);
432#endif /* MODULE */