Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1/*
  2	es3210.c
  3
  4	Linux driver for Racal-Interlan ES3210 EISA Network Adapter
  5
  6	Copyright (C) 1996, Paul Gortmaker.
  7
  8	This software may be used and distributed according to the terms
  9	of the GNU General Public License, incorporated herein by reference.
 10
 11	Information and Code Sources:
 12
 13	1) The existing myriad of Linux 8390 drivers written by Donald Becker.
 14
 15	2) Once again Russ Nelson's asm packet driver provided additional info.
 16
 17	3) Info for getting IRQ and sh-mem gleaned from the EISA cfg files.
 18	   Too bad it doesn't work -- see below.
 19
 20	The ES3210 is an EISA shared memory NS8390 implementation. Note
 21	that all memory copies to/from the board must be 32bit transfers.
 22	Which rules out using eth_io_copy_and_sum() in this driver.
 23
 24	Apparently there are two slightly different revisions of the
 25	card, since there are two distinct EISA cfg files (!rii0101.cfg
 26	and !rii0102.cfg) One has media select in the cfg file and the
 27	other doesn't. Hopefully this will work with either.
 28
 29	That is about all I can tell you about it, having never actually
 30	even seen one of these cards. :)  Try http://www.interlan.com
 31	if you want more info.
 32
 33	Thanks go to Mark Salazar for testing v0.02 of this driver.
 34
 35	Bugs, to-fix, etc:
 36
 37	1) The EISA cfg ports that are *supposed* to have the IRQ and shared
 38	   mem values just read 0xff all the time. Hrrmpf. Apparently the
 39	   same happens with the packet driver as the code for reading
 40	   these registers is disabled there. In the meantime, boot with:
 41	   ether=<IRQ>,0,0x<shared_mem_addr>,eth0 to override the IRQ and
 42	   shared memory detection. (The i/o port detection is okay.)
 43
 44	2) Module support currently untested. Probably works though.
 45
 46*/
 47
 48static const char version[] =
 49	"es3210.c: Driver revision v0.03, 14/09/96\n";
 50
 51#include <linux/module.h>
 52#include <linux/eisa.h>
 53#include <linux/kernel.h>
 54#include <linux/errno.h>
 55#include <linux/string.h>
 56#include <linux/init.h>
 57#include <linux/interrupt.h>
 58#include <linux/netdevice.h>
 59#include <linux/etherdevice.h>
 60
 61#include <asm/io.h>
 62#include <asm/system.h>
 63
 64#include "8390.h"
 65
 66static int es_probe1(struct net_device *dev, int ioaddr);
 67
 68static void es_reset_8390(struct net_device *dev);
 69
 70static void es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page);
 71static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset);
 72static void es_block_output(struct net_device *dev, int count, const unsigned char *buf, int start_page);
 73
 74#define ES_START_PG	0x00    /* First page of TX buffer		*/
 75#define ES_STOP_PG	0x40    /* Last page +1 of RX ring		*/
 76
 77#define ES_IO_EXTENT	0x37	/* The cfg file says 0xc90 -> 0xcc7	*/
 78#define ES_ID_PORT	0xc80	/* Same for all EISA cards 		*/
 79#define ES_SA_PROM	0xc90	/* Start of e'net addr.			*/
 80#define ES_RESET_PORT	0xc84	/* From the packet driver source	*/
 81#define ES_NIC_OFFSET	0xca0	/* Hello, the 8390 is *here*		*/
 82
 83#define ES_ADDR0	0x02	/* 3 byte vendor prefix			*/
 84#define ES_ADDR1	0x07
 85#define ES_ADDR2	0x01
 86
 87/*
 88 * Two card revisions. EISA ID's are always rev. minor, rev. major,, and
 89 * then the three vendor letters stored in 5 bits each, with an "a" = 1.
 90 * For eg: "rii" = 10010 01001 01001 = 0x4929, which is how the EISA
 91 * config utility determines automagically what config file(s) to use.
 92 */
 93#define ES_EISA_ID1	0x01012949	/* !rii0101.cfg 		*/
 94#define ES_EISA_ID2	0x02012949	/* !rii0102.cfg 		*/
 95
 96#define ES_CFG1		0xcc0	/* IOPORT(1) --> IOPORT(6) in cfg file	*/
 97#define ES_CFG2		0xcc1
 98#define ES_CFG3		0xcc2
 99#define ES_CFG4		0xcc3
100#define ES_CFG5		0xcc4
101#define ES_CFG6		0xc84	/* NB: 0xc84 is also "reset" port.	*/
102
103/*
104 *	You can OR any of the following bits together and assign it
105 *	to ES_DEBUG to get verbose driver info during operation.
106 *	Some of these don't do anything yet.
107 */
108
109#define ES_D_PROBE	0x01
110#define ES_D_RX_PKT	0x02
111#define ES_D_TX_PKT	0x04
112#define ED_D_IRQ	0x08
113
114#define ES_DEBUG	0
115
116static unsigned char lo_irq_map[] __initdata = {3, 4, 5, 6, 7, 9, 10};
117static unsigned char hi_irq_map[] __initdata = {11, 12, 0, 14, 0, 0, 0, 15};
118
119/*
120 *	Probe for the card. The best way is to read the EISA ID if it
121 *	is known. Then we check the prefix of the station address
122 *	PROM for a match against the Racal-Interlan assigned value.
123 */
124
125static int __init do_es_probe(struct net_device *dev)
126{
127	unsigned short ioaddr = dev->base_addr;
128	int irq = dev->irq;
129	int mem_start = dev->mem_start;
130
131	if (ioaddr > 0x1ff)		/* Check a single specified location. */
132		return es_probe1(dev, ioaddr);
133	else if (ioaddr > 0)		/* Don't probe at all. */
134		return -ENXIO;
135
136	if (!EISA_bus) {
137#if ES_DEBUG & ES_D_PROBE
138		printk("es3210.c: Not EISA bus. Not probing high ports.\n");
139#endif
140		return -ENXIO;
141	}
142
143	/* EISA spec allows for up to 16 slots, but 8 is typical. */
144	for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
145		if (es_probe1(dev, ioaddr) == 0)
146			return 0;
147		dev->irq = irq;
148		dev->mem_start = mem_start;
149	}
150
151	return -ENODEV;
152}
153
154#ifndef MODULE
155struct net_device * __init es_probe(int unit)
156{
157	struct net_device *dev = alloc_ei_netdev();
158	int err;
159
160	if (!dev)
161		return ERR_PTR(-ENOMEM);
162
163	sprintf(dev->name, "eth%d", unit);
164	netdev_boot_setup_check(dev);
165
166	err = do_es_probe(dev);
167	if (err)
168		goto out;
169	return dev;
170out:
171	free_netdev(dev);
172	return ERR_PTR(err);
173}
174#endif
175
176static int __init es_probe1(struct net_device *dev, int ioaddr)
177{
178	int i, retval;
179	unsigned long eisa_id;
180
181	if (!request_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT, "es3210"))
182		return -ENODEV;
183
184#if ES_DEBUG & ES_D_PROBE
185	printk("es3210.c: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + ES_ID_PORT));
186	printk("es3210.c: config regs: %#x %#x %#x %#x %#x %#x\n",
187		inb(ioaddr + ES_CFG1), inb(ioaddr + ES_CFG2), inb(ioaddr + ES_CFG3),
188		inb(ioaddr + ES_CFG4), inb(ioaddr + ES_CFG5), inb(ioaddr + ES_CFG6));
189#endif
190
191/*	Check the EISA ID of the card. */
192	eisa_id = inl(ioaddr + ES_ID_PORT);
193	if ((eisa_id != ES_EISA_ID1) && (eisa_id != ES_EISA_ID2)) {
194		retval = -ENODEV;
195		goto out;
196	}
197
198	for (i = 0; i < ETHER_ADDR_LEN ; i++)
199		dev->dev_addr[i] = inb(ioaddr + ES_SA_PROM + i);
200
201/*	Check the Racal vendor ID as well. */
202	if (dev->dev_addr[0] != ES_ADDR0 ||
203	    dev->dev_addr[1] != ES_ADDR1 ||
204	    dev->dev_addr[2] != ES_ADDR2) {
205		printk("es3210.c: card not found %pM (invalid_prefix).\n",
206		       dev->dev_addr);
207		retval = -ENODEV;
208		goto out;
209	}
210
211	printk("es3210.c: ES3210 rev. %ld at %#x, node %pM",
212	       eisa_id>>24, ioaddr, dev->dev_addr);
213
214	/* Snarf the interrupt now. */
215	if (dev->irq == 0) {
216		unsigned char hi_irq = inb(ioaddr + ES_CFG2) & 0x07;
217		unsigned char lo_irq = inb(ioaddr + ES_CFG1) & 0xfe;
218
219		if (hi_irq != 0) {
220			dev->irq = hi_irq_map[hi_irq - 1];
221		} else {
222			int i = 0;
223			while (lo_irq > (1<<i)) i++;
224			dev->irq = lo_irq_map[i];
225		}
226		printk(" using IRQ %d", dev->irq);
227#if ES_DEBUG & ES_D_PROBE
228		printk("es3210.c: hi_irq %#x, lo_irq %#x, dev->irq = %d\n",
229					hi_irq, lo_irq, dev->irq);
230#endif
231	} else {
232		if (dev->irq == 2)
233			dev->irq = 9;			/* Doh! */
234		printk(" assigning IRQ %d", dev->irq);
235	}
236
237	if (request_irq(dev->irq, ei_interrupt, 0, "es3210", dev)) {
238		printk (" unable to get IRQ %d.\n", dev->irq);
239		retval = -EAGAIN;
240		goto out;
241	}
242
243	if (dev->mem_start == 0) {
244		unsigned char mem_enabled = inb(ioaddr + ES_CFG2) & 0xc0;
245		unsigned char mem_bits = inb(ioaddr + ES_CFG3) & 0x07;
246
247		if (mem_enabled != 0x80) {
248			printk(" shared mem disabled - giving up\n");
249			retval = -ENXIO;
250			goto out1;
251		}
252		dev->mem_start = 0xC0000 + mem_bits*0x4000;
253		printk(" using ");
254	} else {
255		printk(" assigning ");
256	}
257
258	ei_status.mem = ioremap(dev->mem_start, (ES_STOP_PG - ES_START_PG)*256);
259	if (!ei_status.mem) {
260		printk("ioremap failed - giving up\n");
261		retval = -ENXIO;
262		goto out1;
263	}
264
265	dev->mem_end = dev->mem_start + (ES_STOP_PG - ES_START_PG)*256;
266
267	printk("mem %#lx-%#lx\n", dev->mem_start, dev->mem_end-1);
268
269#if ES_DEBUG & ES_D_PROBE
270	if (inb(ioaddr + ES_CFG5))
271		printk("es3210: Warning - DMA channel enabled, but not used here.\n");
272#endif
273	/* Note, point at the 8390, and not the card... */
274	dev->base_addr = ioaddr + ES_NIC_OFFSET;
275
276	ei_status.name = "ES3210";
277	ei_status.tx_start_page = ES_START_PG;
278	ei_status.rx_start_page = ES_START_PG + TX_PAGES;
279	ei_status.stop_page = ES_STOP_PG;
280	ei_status.word16 = 1;
281
282	if (ei_debug > 0)
283		printk(version);
284
285	ei_status.reset_8390 = &es_reset_8390;
286	ei_status.block_input = &es_block_input;
287	ei_status.block_output = &es_block_output;
288	ei_status.get_8390_hdr = &es_get_8390_hdr;
289
290	dev->netdev_ops = &ei_netdev_ops;
291	NS8390_init(dev, 0);
292
293	retval = register_netdev(dev);
294	if (retval)
295		goto out1;
296	return 0;
297out1:
298	free_irq(dev->irq, dev);
299out:
300	release_region(ioaddr + ES_SA_PROM, ES_IO_EXTENT);
301	return retval;
302}
303
304/*
305 *	Reset as per the packet driver method. Judging by the EISA cfg
306 *	file, this just toggles the "Board Enable" bits (bit 2 and 0).
307 */
308
309static void es_reset_8390(struct net_device *dev)
310{
311	unsigned short ioaddr = dev->base_addr;
312	unsigned long end;
313
314	outb(0x04, ioaddr + ES_RESET_PORT);
315	if (ei_debug > 1) printk("%s: resetting the ES3210...", dev->name);
316
317	end = jiffies + 2*HZ/100;
318        while ((signed)(end - jiffies) > 0) continue;
319
320	ei_status.txing = 0;
321	outb(0x01, ioaddr + ES_RESET_PORT);
322	if (ei_debug > 1) printk("reset done\n");
323}
324
325/*
326 *	Note: In the following three functions is the implicit assumption
327 *	that the associated memcpy will only use "rep; movsl" as long as
328 *	we keep the counts as some multiple of doublewords. This is a
329 *	requirement of the hardware, and also prevents us from using
330 *	eth_io_copy_and_sum() since we can't guarantee it will limit
331 *	itself to doubleword access.
332 */
333
334/*
335 *	Grab the 8390 specific header. Similar to the block_input routine, but
336 *	we don't need to be concerned with ring wrap as the header will be at
337 *	the start of a page, so we optimize accordingly. (A single doubleword.)
338 */
339
340static void
341es_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
342{
343	void __iomem *hdr_start = ei_status.mem + ((ring_page - ES_START_PG)<<8);
344	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
345	hdr->count = (hdr->count + 3) & ~3;     /* Round up allocation. */
346}
347
348/*
349 *	Block input and output are easy on shared memory ethercards, the only
350 *	complication is when the ring buffer wraps. The count will already
351 *	be rounded up to a doubleword value via es_get_8390_hdr() above.
352 */
353
354static void es_block_input(struct net_device *dev, int count, struct sk_buff *skb,
355						  int ring_offset)
356{
357	void __iomem *xfer_start = ei_status.mem + ring_offset - ES_START_PG*256;
358
359	if (ring_offset + count > ES_STOP_PG*256) {
360		/* Packet wraps over end of ring buffer. */
361		int semi_count = ES_STOP_PG*256 - ring_offset;
362		memcpy_fromio(skb->data, xfer_start, semi_count);
363		count -= semi_count;
364		memcpy_fromio(skb->data + semi_count, ei_status.mem, count);
365	} else {
366		/* Packet is in one chunk. */
367		memcpy_fromio(skb->data, xfer_start, count);
368	}
369}
370
371static void es_block_output(struct net_device *dev, int count,
372				const unsigned char *buf, int start_page)
373{
374	void __iomem *shmem = ei_status.mem + ((start_page - ES_START_PG)<<8);
375
376	count = (count + 3) & ~3;     /* Round up to doubleword */
377	memcpy_toio(shmem, buf, count);
378}
379
380#ifdef MODULE
381#define MAX_ES_CARDS	4	/* Max number of ES3210 cards per module */
382#define NAMELEN		8	/* # of chars for storing dev->name */
383static struct net_device *dev_es3210[MAX_ES_CARDS];
384static int io[MAX_ES_CARDS];
385static int irq[MAX_ES_CARDS];
386static int mem[MAX_ES_CARDS];
387
388module_param_array(io, int, NULL, 0);
389module_param_array(irq, int, NULL, 0);
390module_param_array(mem, int, NULL, 0);
391MODULE_PARM_DESC(io, "I/O base address(es)");
392MODULE_PARM_DESC(irq, "IRQ number(s)");
393MODULE_PARM_DESC(mem, "memory base address(es)");
394MODULE_DESCRIPTION("Racal-Interlan ES3210 EISA ethernet driver");
395MODULE_LICENSE("GPL");
396
397int __init init_module(void)
398{
399	struct net_device *dev;
400	int this_dev, found = 0;
401
402	for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) {
403		if (io[this_dev] == 0 && this_dev != 0)
404			break;
405		dev = alloc_ei_netdev();
406		if (!dev)
407			break;
408		dev->irq = irq[this_dev];
409		dev->base_addr = io[this_dev];
410		dev->mem_start = mem[this_dev];
411		if (do_es_probe(dev) == 0) {
412			dev_es3210[found++] = dev;
413			continue;
414		}
415		free_netdev(dev);
416		printk(KERN_WARNING "es3210.c: No es3210 card found (i/o = 0x%x).\n", io[this_dev]);
417		break;
418	}
419	if (found)
420		return 0;
421	return -ENXIO;
422}
423
424static void cleanup_card(struct net_device *dev)
425{
426	free_irq(dev->irq, dev);
427	release_region(dev->base_addr, ES_IO_EXTENT);
428	iounmap(ei_status.mem);
429}
430
431void __exit
432cleanup_module(void)
433{
434	int this_dev;
435
436	for (this_dev = 0; this_dev < MAX_ES_CARDS; this_dev++) {
437		struct net_device *dev = dev_es3210[this_dev];
438		if (dev) {
439			unregister_netdev(dev);
440			cleanup_card(dev);
441			free_netdev(dev);
442		}
443	}
444}
445#endif /* MODULE */
446