Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  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/io.h>
 38#include <asm/irq.h>
 39
 40#include "8390.h"
 41
 42#define DRV_NAME	"ac3200"
 43
 44/* Offsets from the base address. */
 45#define AC_NIC_BASE	0x00
 46#define AC_SA_PROM	0x16			/* The station address PROM. */
 47#define AC_ADDR0	0x00			/* Prefix station address values. */
 48#define AC_ADDR1	0x40
 49#define AC_ADDR2	0x90
 50#define AC_ID_PORT	0xC80
 51#define AC_EISA_ID	0x0110d305
 52#define AC_RESET_PORT	0xC84
 53#define AC_RESET	0x00
 54#define AC_ENABLE	0x01
 55#define AC_CONFIG	0xC90	/* The configuration port. */
 56
 57#define AC_IO_EXTENT 0x20
 58                                /* Actually accessed is:
 59								 * AC_NIC_BASE (0-15)
 60								 * AC_SA_PROM (0-5)
 61								 * AC_ID_PORT (0-3)
 62								 * AC_RESET_PORT
 63								 * AC_CONFIG
 64								 */
 65
 66/* Decoding of the configuration register. */
 67static unsigned char config2irqmap[8] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
 68static int addrmap[8] =
 69{0xFF0000, 0xFE0000, 0xFD0000, 0xFFF0000, 0xFFE0000, 0xFFC0000,  0xD0000, 0 };
 70static const char *port_name[4] = { "10baseT", "invalid", "AUI", "10base2"};
 71
 72#define config2irq(configval)	config2irqmap[((configval) >> 3) & 7]
 73#define config2mem(configval)	addrmap[(configval) & 7]
 74#define config2name(configval)	port_name[((configval) >> 6) & 3]
 75
 76/* First and last 8390 pages. */
 77#define AC_START_PG		0x00	/* First page of 8390 TX buffer */
 78#define AC_STOP_PG		0x80	/* Last page +1 of the 8390 RX ring */
 79
 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
100static int __init do_ac3200_probe(struct net_device *dev)
101{
102	unsigned short ioaddr = dev->base_addr;
103	int irq = dev->irq;
104	int mem_start = dev->mem_start;
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		dev->irq = irq;
118		dev->mem_start = mem_start;
119	}
120
121	return -ENODEV;
122}
123
124#ifndef MODULE
125struct net_device * __init ac3200_probe(int unit)
126{
127	struct net_device *dev = alloc_ei_netdev();
128	int err;
129
130	if (!dev)
131		return ERR_PTR(-ENOMEM);
132
133	sprintf(dev->name, "eth%d", unit);
134	netdev_boot_setup_check(dev);
135
136	err = do_ac3200_probe(dev);
137	if (err)
138		goto out;
139	return dev;
140out:
141	free_netdev(dev);
142	return ERR_PTR(err);
143}
144#endif
145
146static const struct net_device_ops ac_netdev_ops = {
147	.ndo_open		= ac_open,
148	.ndo_stop 		= ac_close_card,
149
150	.ndo_start_xmit		= ei_start_xmit,
151	.ndo_tx_timeout		= ei_tx_timeout,
152	.ndo_get_stats		= ei_get_stats,
153	.ndo_set_rx_mode	= ei_set_multicast_list,
154	.ndo_validate_addr	= eth_validate_addr,
155	.ndo_set_mac_address 	= eth_mac_addr,
156	.ndo_change_mtu		= eth_change_mtu,
157#ifdef CONFIG_NET_POLL_CONTROLLER
158	.ndo_poll_controller	= ei_poll,
159#endif
160};
161
162static int __init ac_probe1(int ioaddr, struct net_device *dev)
163{
164	int i, retval;
165
166	if (!request_region(ioaddr, AC_IO_EXTENT, DRV_NAME))
167		return -EBUSY;
168
169	if (inb_p(ioaddr + AC_ID_PORT) == 0xff) {
170		retval = -ENODEV;
171		goto out;
172	}
173
174	if (inl(ioaddr + AC_ID_PORT) != AC_EISA_ID) {
175		retval = -ENODEV;
176		goto out;
177	}
178
179#ifndef final_version
180	printk(KERN_DEBUG "AC3200 ethercard configuration register is %#02x,"
181		   " EISA ID %02x %02x %02x %02x.\n", inb(ioaddr + AC_CONFIG),
182		   inb(ioaddr + AC_ID_PORT + 0), inb(ioaddr + AC_ID_PORT + 1),
183		   inb(ioaddr + AC_ID_PORT + 2), inb(ioaddr + AC_ID_PORT + 3));
184#endif
185
186	for (i = 0; i < 6; i++)
187		dev->dev_addr[i] = inb(ioaddr + AC_SA_PROM + i);
188
189	printk(KERN_DEBUG "AC3200 in EISA slot %d, node %pM",
190	       ioaddr/0x1000, dev->dev_addr);
191#if 0
192	/* Check the vendor ID/prefix. Redundant after checking the EISA ID */
193	if (inb(ioaddr + AC_SA_PROM + 0) != AC_ADDR0
194		|| inb(ioaddr + AC_SA_PROM + 1) != AC_ADDR1
195		|| inb(ioaddr + AC_SA_PROM + 2) != AC_ADDR2 ) {
196		printk(", not found (invalid prefix).\n");
197		retval = -ENODEV;
198		goto out;
199	}
200#endif
201
202	/* Assign and allocate the interrupt now. */
203	if (dev->irq == 0) {
204		dev->irq = config2irq(inb(ioaddr + AC_CONFIG));
205		printk(", using");
206	} else {
207		dev->irq = irq_canonicalize(dev->irq);
208		printk(", assigning");
209	}
210
211	retval = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
212	if (retval) {
213		printk (" nothing! Unable to get IRQ %d.\n", dev->irq);
214		goto out;
215	}
216
217	printk(" IRQ %d, %s port\n", dev->irq, port_name[dev->if_port]);
218
219	dev->base_addr = ioaddr;
220
221#ifdef notyet
222	if (dev->mem_start)	{		/* Override the value from the board. */
223		for (i = 0; i < 7; i++)
224			if (addrmap[i] == dev->mem_start)
225				break;
226		if (i >= 7)
227			i = 0;
228		outb((inb(ioaddr + AC_CONFIG) & ~7) | i, ioaddr + AC_CONFIG);
229	}
230#endif
231
232	dev->if_port = inb(ioaddr + AC_CONFIG) >> 6;
233	dev->mem_start = config2mem(inb(ioaddr + AC_CONFIG));
234
235	printk("%s: AC3200 at %#3x with %dkB memory at physical address %#lx.\n",
236			dev->name, ioaddr, AC_STOP_PG/4, dev->mem_start);
237
238	/*
239	 *  BEWARE!! Some dain-bramaged EISA SCUs will allow you to put
240	 *  the card mem within the region covered by `normal' RAM  !!!
241	 *
242	 *  ioremap() will fail in that case.
243	 */
244	ei_status.mem = ioremap(dev->mem_start, AC_STOP_PG*0x100);
245	if (!ei_status.mem) {
246		printk(KERN_ERR "ac3200.c: Unable to remap card memory above 1MB !!\n");
247		printk(KERN_ERR "ac3200.c: Try using EISA SCU to set memory below 1MB.\n");
248		printk(KERN_ERR "ac3200.c: Driver NOT installed.\n");
249		retval = -EINVAL;
250		goto out1;
251	}
252	printk("ac3200.c: remapped %dkB card memory to virtual address %p\n",
253			AC_STOP_PG/4, ei_status.mem);
254
255	dev->mem_start = (unsigned long)ei_status.mem;
256	dev->mem_end = dev->mem_start + (AC_STOP_PG - AC_START_PG)*256;
257
258	ei_status.name = "AC3200";
259	ei_status.tx_start_page = AC_START_PG;
260	ei_status.rx_start_page = AC_START_PG + TX_PAGES;
261	ei_status.stop_page = AC_STOP_PG;
262	ei_status.word16 = 1;
263
264	if (ei_debug > 0)
265		printk(version);
266
267	ei_status.reset_8390 = &ac_reset_8390;
268	ei_status.block_input = &ac_block_input;
269	ei_status.block_output = &ac_block_output;
270	ei_status.get_8390_hdr = &ac_get_8390_hdr;
271
272	dev->netdev_ops = &ac_netdev_ops;
273	NS8390_init(dev, 0);
274
275	retval = register_netdev(dev);
276	if (retval)
277		goto out2;
278	return 0;
279out2:
280	if (ei_status.reg0)
281		iounmap(ei_status.mem);
282out1:
283	free_irq(dev->irq, dev);
284out:
285	release_region(ioaddr, AC_IO_EXTENT);
286	return retval;
287}
288
289static int ac_open(struct net_device *dev)
290{
291#ifdef notyet
292	/* Someday we may enable the IRQ and shared memory here. */
293	int ioaddr = dev->base_addr;
294#endif
295
296	ei_open(dev);
297	return 0;
298}
299
300static void ac_reset_8390(struct net_device *dev)
301{
302	ushort ioaddr = dev->base_addr;
303
304	outb(AC_RESET, ioaddr + AC_RESET_PORT);
305	if (ei_debug > 1) printk("resetting AC3200, t=%ld...", jiffies);
306
307	ei_status.txing = 0;
308	outb(AC_ENABLE, ioaddr + AC_RESET_PORT);
309	if (ei_debug > 1) printk("reset done\n");
310}
311
312/* Grab the 8390 specific header. Similar to the block_input routine, but
313   we don't need to be concerned with ring wrap as the header will be at
314   the start of a page, so we optimize accordingly. */
315
316static void
317ac_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
318{
319	void __iomem *hdr_start = ei_status.mem + ((ring_page - AC_START_PG)<<8);
320	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
321}
322
323/*  Block input and output are easy on shared memory ethercards, the only
324	complication is when the ring buffer wraps. */
325
326static void ac_block_input(struct net_device *dev, int count, struct sk_buff *skb,
327						  int ring_offset)
328{
329	void __iomem *start = ei_status.mem + ring_offset - AC_START_PG*256;
330
331	if (ring_offset + count > AC_STOP_PG*256) {
332		/* We must wrap the input move. */
333		int semi_count = AC_STOP_PG*256 - ring_offset;
334		memcpy_fromio(skb->data, start, semi_count);
335		count -= semi_count;
336		memcpy_fromio(skb->data + semi_count,
337				ei_status.mem + TX_PAGES*256, count);
338	} else {
339		memcpy_fromio(skb->data, start, count);
340	}
341}
342
343static void ac_block_output(struct net_device *dev, int count,
344							const unsigned char *buf, int start_page)
345{
346	void __iomem *shmem = ei_status.mem + ((start_page - AC_START_PG)<<8);
347
348	memcpy_toio(shmem, buf, count);
349}
350
351static int ac_close_card(struct net_device *dev)
352{
353	if (ei_debug > 1)
354		printk("%s: Shutting down ethercard.\n", dev->name);
355
356#ifdef notyet
357	/* We should someday disable shared memory and interrupts. */
358	outb(0x00, ioaddr + 6);	/* Disable interrupts. */
359	free_irq(dev->irq, dev);
360#endif
361
362	ei_close(dev);
363	return 0;
364}
365
366#ifdef MODULE
367#define MAX_AC32_CARDS	4	/* Max number of AC32 cards per module */
368static struct net_device *dev_ac32[MAX_AC32_CARDS];
369static int io[MAX_AC32_CARDS];
370static int irq[MAX_AC32_CARDS];
371static int mem[MAX_AC32_CARDS];
372module_param_array(io, int, NULL, 0);
373module_param_array(irq, int, NULL, 0);
374module_param_array(mem, int, NULL, 0);
375MODULE_PARM_DESC(io, "I/O base address(es)");
376MODULE_PARM_DESC(irq, "IRQ number(s)");
377MODULE_PARM_DESC(mem, "Memory base address(es)");
378MODULE_DESCRIPTION("Ansel AC3200 EISA ethernet driver");
379MODULE_LICENSE("GPL");
380
381static int __init ac3200_module_init(void)
382{
383	struct net_device *dev;
384	int this_dev, found = 0;
385
386	for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
387		if (io[this_dev] == 0 && this_dev != 0)
388			break;
389		dev = alloc_ei_netdev();
390		if (!dev)
391			break;
392		dev->irq = irq[this_dev];
393		dev->base_addr = io[this_dev];
394		dev->mem_start = mem[this_dev];		/* Currently ignored by driver */
395		if (do_ac3200_probe(dev) == 0) {
396			dev_ac32[found++] = dev;
397			continue;
398		}
399		free_netdev(dev);
400		printk(KERN_WARNING "ac3200.c: No ac3200 card found (i/o = 0x%x).\n", io[this_dev]);
401		break;
402	}
403	if (found)
404		return 0;
405	return -ENXIO;
406}
407
408static void cleanup_card(struct net_device *dev)
409{
410	/* Someday free_irq may be in ac_close_card() */
411	free_irq(dev->irq, dev);
412	release_region(dev->base_addr, AC_IO_EXTENT);
413	iounmap(ei_status.mem);
414}
415
416static void __exit ac3200_module_exit(void)
417{
418	int this_dev;
419
420	for (this_dev = 0; this_dev < MAX_AC32_CARDS; this_dev++) {
421		struct net_device *dev = dev_ac32[this_dev];
422		if (dev) {
423			unregister_netdev(dev);
424			cleanup_card(dev);
425			free_netdev(dev);
426		}
427	}
428}
429module_init(ac3200_module_init);
430module_exit(ac3200_module_exit);
431#endif /* MODULE */