File: /usr/src/linux/drivers/net/e2100.c

1     /* e2100.c: A Cabletron E2100 series ethernet driver for linux. */
2     /*
3     	Written 1993-1994 by Donald Becker.
4     
5     	Copyright 1994 by Donald Becker.
6     	Copyright 1993 United States Government as represented by the
7     	Director, National Security Agency.  This software may be used and
8     	distributed according to the terms of the GNU General Public License,
9     	incorporated herein by reference.
10     
11     	This is a driver for the Cabletron E2100 series ethercards.
12     
13     	The Author may be reached as becker@scyld.com, or C/O
14     	Scyld Computing Corporation
15     	410 Severn Ave., Suite 210
16     	Annapolis MD 21403
17     
18     	The E2100 series ethercard is a fairly generic shared memory 8390
19     	implementation.  The only unusual aspect is the way the shared memory
20     	registers are set: first you do an inb() in what is normally the
21     	station address region, and the low three bits of next outb() *address*
22     	is used	as the write value for that register.  Either someone wasn't
23     	too used to dem bit en bites, or they were trying to obfuscate the
24     	programming interface.
25     
26     	There is an additional complication when setting the window on the packet
27     	buffer.  You must first do a read into the packet buffer region with the
28     	low 8 address bits the address setting the page for the start of the packet
29     	buffer window, and then do the above operation.  See mem_on() for details.
30     
31     	One bug on the chip is that even a hard reset won't disable the memory
32     	window, usually resulting in a hung machine if mem_off() isn't called.
33     	If this happens, you must power down the machine for about 30 seconds.
34     */
35     
36     static const char version[] =
37     	"e2100.c:v1.01 7/21/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
38     
39     #include <linux/module.h>
40     
41     #include <linux/kernel.h>
42     #include <linux/sched.h>
43     #include <linux/errno.h>
44     #include <linux/string.h>
45     #include <linux/ioport.h>
46     #include <linux/netdevice.h>
47     #include <linux/etherdevice.h>
48     #include <linux/init.h>
49     #include <linux/delay.h>
50     
51     #include <asm/io.h>
52     #include <asm/system.h>
53     
54     #include "8390.h"
55     
56     static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0};
57     
58     /* Offsets from the base_addr.
59        Read from the ASIC register, and the low three bits of the next outb()
60        address is used to set the corresponding register. */
61     #define E21_NIC_OFFSET  0		/* Offset to the 8390 NIC. */
62     #define E21_ASIC		0x10
63     #define E21_MEM_ENABLE	0x10
64     #define  E21_MEM_ON		0x05	/* Enable memory in 16 bit mode. */
65     #define  E21_MEM_ON_8	0x07	/* Enable memory in  8 bit mode. */
66     #define E21_MEM_BASE	0x11
67     #define E21_IRQ_LOW		0x12	/* The low three bits of the IRQ number. */
68     #define E21_IRQ_HIGH	0x14	/* The high IRQ bit and media select ...  */
69     #define E21_MEDIA		0x14	/* (alias). */
70     #define  E21_ALT_IFPORT 0x02	/* Set to use the other (BNC,AUI) port. */
71     #define  E21_BIG_MEM	0x04	/* Use a bigger (64K) buffer (we don't) */
72     #define E21_SAPROM		0x10	/* Offset to station address data. */
73     #define E21_IO_EXTENT	 0x20
74     
75     extern inline void mem_on(short port, volatile char *mem_base,
76     						  unsigned char start_page )
77     {
78     	/* This is a little weird: set the shared memory window by doing a
79     	   read.  The low address bits specify the starting page. */
80     	readb(mem_base+start_page);
81     	inb(port + E21_MEM_ENABLE);
82     	outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON);
83     }
84     
85     extern inline void mem_off(short port)
86     {
87     	inb(port + E21_MEM_ENABLE);
88     	outb(0x00, port + E21_MEM_ENABLE);
89     }
90     
91     /* In other drivers I put the TX pages first, but the E2100 window circuitry
92        is designed to have a 4K Tx region last. The windowing circuitry wraps the
93        window at 0x2fff->0x0000 so that the packets at e.g. 0x2f00 in the RX ring
94        appear contiguously in the window. */
95     #define E21_RX_START_PG		0x00	/* First page of RX buffer */
96     #define E21_RX_STOP_PG		0x30	/* Last page +1 of RX ring */
97     #define E21_BIG_RX_STOP_PG	0xF0	/* Last page +1 of RX ring */
98     #define E21_TX_START_PG		E21_RX_STOP_PG	/* First page of TX buffer */
99     
100     int e2100_probe(struct net_device *dev);
101     static int e21_probe1(struct net_device *dev, int ioaddr);
102     
103     static int e21_open(struct net_device *dev);
104     static void e21_reset_8390(struct net_device *dev);
105     static void e21_block_input(struct net_device *dev, int count,
106     						   struct sk_buff *skb, int ring_offset);
107     static void e21_block_output(struct net_device *dev, int count,
108     							 const unsigned char *buf, int start_page);
109     static void e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
110     							int ring_page);
111     
112     static int e21_close(struct net_device *dev);
113     
114     
115     /*  Probe for the E2100 series ethercards.  These cards have an 8390 at the
116     	base address and the station address at both offset 0x10 and 0x18.  I read
117     	the station address from offset 0x18 to avoid the dataport of NE2000
118     	ethercards, and look for Ctron's unique ID (first three octets of the
119     	station address).
120      */
121     
122     int  __init e2100_probe(struct net_device *dev)
123     {
124     	int *port;
125     	int base_addr = dev->base_addr;
126     
127     	SET_MODULE_OWNER(dev);
128     
129     	if (base_addr > 0x1ff)		/* Check a single specified location. */
130     		return e21_probe1(dev, base_addr);
131     	else if (base_addr != 0)	/* Don't probe at all. */
132     		return -ENXIO;
133     
134     	for (port = e21_probe_list; *port; port++)
135     		if (e21_probe1(dev, *port) == 0)
136     			return 0;
137     
138     	return -ENODEV;
139     }
140     
141     static int __init e21_probe1(struct net_device *dev, int ioaddr)
142     {
143     	int i, status, retval;
144     	unsigned char *station_addr = dev->dev_addr;
145     	static unsigned version_printed;
146     
147     	if (!request_region(ioaddr, E21_IO_EXTENT, dev->name))
148     		return -EBUSY;
149     
150     	/* First check the station address for the Ctron prefix. */
151     	if (inb(ioaddr + E21_SAPROM + 0) != 0x00
152     		|| inb(ioaddr + E21_SAPROM + 1) != 0x00
153     		|| inb(ioaddr + E21_SAPROM + 2) != 0x1d) {
154     		retval = -ENODEV;
155     		goto out;
156     	}
157     
158     	/* Verify by making certain that there is a 8390 at there. */
159     	outb(E8390_NODMA + E8390_STOP, ioaddr);
160     	udelay(1);	/* we want to delay one I/O cycle - which is 2MHz */
161     	status = inb(ioaddr);
162     	if (status != 0x21 && status != 0x23) {
163     		retval = -ENODEV;
164     		goto out;
165     	}
166     
167     	/* Read the station address PROM.  */
168     	for (i = 0; i < 6; i++)
169     		station_addr[i] = inb(ioaddr + E21_SAPROM + i);
170     
171     	inb(ioaddr + E21_MEDIA); 		/* Point to media selection. */
172     	outb(0, ioaddr + E21_ASIC); 	/* and disable the secondary interface. */
173     
174     	if (ei_debug  &&  version_printed++ == 0)
175     		printk(version);
176     
177     	for (i = 0; i < 6; i++)
178     		printk(" %02X", station_addr[i]);
179     
180     	/* Allocate dev->priv and fill in 8390 specific dev fields. */
181     	if (ethdev_init(dev)) {
182     		printk (" unable to get memory for dev->priv.\n");
183     		retval = -ENOMEM;
184     		goto out;
185     	}
186     
187     	if (dev->irq < 2) {
188     		int irqlist[] = {15,11,10,12,5,9,3,4}, i;
189     		for (i = 0; i < 8; i++)
190     			if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) {
191     				dev->irq = irqlist[i];
192     				break;
193     			}
194     		if (i >= 8) {
195     			printk(" unable to get IRQ %d.\n", dev->irq);
196     			kfree(dev->priv);
197     			dev->priv = NULL;
198     			retval = -EAGAIN;
199     			goto out;
200     		}
201     	} else if (dev->irq == 2)	/* Fixup luser bogosity: IRQ2 is really IRQ9 */
202     		dev->irq = 9;
203     
204     	/* The 8390 is at the base address. */
205     	dev->base_addr = ioaddr;
206     
207     	ei_status.name = "E2100";
208     	ei_status.word16 = 1;
209     	ei_status.tx_start_page = E21_TX_START_PG;
210     	ei_status.rx_start_page = E21_RX_START_PG;
211     	ei_status.stop_page = E21_RX_STOP_PG;
212     	ei_status.saved_irq = dev->irq;
213     
214     	/* Check the media port used.  The port can be passed in on the
215     	   low mem_end bits. */
216     	if (dev->mem_end & 15)
217     		dev->if_port = dev->mem_end & 7;
218     	else {
219     		dev->if_port = 0;
220     		inb(ioaddr + E21_MEDIA); 	/* Turn automatic media detection on. */
221     		for(i = 0; i < 6; i++)
222     			if (station_addr[i] != inb(ioaddr + E21_SAPROM + 8 + i)) {
223     				dev->if_port = 1;
224     				break;
225     			}
226     	}
227     
228     	/* Never map in the E21 shared memory unless you are actively using it.
229     	   Also, the shared memory has effective only one setting -- spread all
230     	   over the 128K region! */
231     	if (dev->mem_start == 0)
232     		dev->mem_start = 0xd0000;
233     
234     #ifdef notdef
235     	/* These values are unused.  The E2100 has a 2K window into the packet
236     	   buffer.  The window can be set to start on any page boundary. */
237     	dev->rmem_start = dev->mem_start + TX_PAGES*256;
238     	dev->mem_end = dev->rmem_end = dev->mem_start + 2*1024;
239     #endif
240     
241     	printk(", IRQ %d, %s media, memory @ %#lx.\n", dev->irq,
242     		   dev->if_port ? "secondary" : "primary", dev->mem_start);
243     
244     	ei_status.reset_8390 = &e21_reset_8390;
245     	ei_status.block_input = &e21_block_input;
246     	ei_status.block_output = &e21_block_output;
247     	ei_status.get_8390_hdr = &e21_get_8390_hdr;
248     	dev->open = &e21_open;
249     	dev->stop = &e21_close;
250     	NS8390_init(dev, 0);
251     
252     	return 0;
253     out:
254     	release_region(ioaddr, E21_IO_EXTENT);
255     	return retval;
256     }
257     
258     static int
259     e21_open(struct net_device *dev)
260     {
261     	short ioaddr = dev->base_addr;
262     	int retval;
263     
264     	if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev)))
265     		return retval;
266     
267     	/* Set the interrupt line and memory base on the hardware. */
268     	inb(ioaddr + E21_IRQ_LOW);
269     	outb(0, ioaddr + E21_ASIC + (dev->irq & 7));
270     	inb(ioaddr + E21_IRQ_HIGH); 			/* High IRQ bit, and if_port. */
271     	outb(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0)
272     		   + (dev->if_port ? E21_ALT_IFPORT : 0));
273     	inb(ioaddr + E21_MEM_BASE);
274     	outb(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7));
275     
276     	ei_open(dev);
277     	return 0;
278     }
279     
280     static void
281     e21_reset_8390(struct net_device *dev)
282     {
283     	short ioaddr = dev->base_addr;
284     
285     	outb(0x01, ioaddr);
286     	if (ei_debug > 1) printk("resetting the E2180x3 t=%ld...", jiffies);
287     	ei_status.txing = 0;
288     
289     	/* Set up the ASIC registers, just in case something changed them. */
290     
291     	if (ei_debug > 1) printk("reset done\n");
292     	return;
293     }
294     
295     /* Grab the 8390 specific header. We put the 2k window so the header page
296        appears at the start of the shared memory. */
297     
298     static void
299     e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
300     {
301     
302     	short ioaddr = dev->base_addr;
303     	char *shared_mem = (char *)dev->mem_start;
304     
305     	mem_on(ioaddr, shared_mem, ring_page);
306     
307     #ifdef notdef
308     	/* Officially this is what we are doing, but the readl() is faster */
309     	memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr));
310     #else
311     	((unsigned int*)hdr)[0] = readl(shared_mem);
312     #endif
313     
314     	/* Turn off memory access: we would need to reprogram the window anyway. */
315     	mem_off(ioaddr);
316     
317     }
318     
319     /*  Block input and output are easy on shared memory ethercards.
320     	The E21xx makes block_input() especially easy by wrapping the top
321     	ring buffer to the bottom automatically. */
322     static void
323     e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
324     {
325     	short ioaddr = dev->base_addr;
326     	char *shared_mem = (char *)dev->mem_start;
327     
328     	mem_on(ioaddr, shared_mem, (ring_offset>>8));
329     
330     	/* Packet is always in one chunk -- we can copy + cksum. */
331     	eth_io_copy_and_sum(skb, dev->mem_start + (ring_offset & 0xff), count, 0);
332     
333     	mem_off(ioaddr);
334     }
335     
336     static void
337     e21_block_output(struct net_device *dev, int count, const unsigned char *buf,
338     				 int start_page)
339     {
340     	short ioaddr = dev->base_addr;
341     	volatile char *shared_mem = (char *)dev->mem_start;
342     
343     	/* Set the shared memory window start by doing a read, with the low address
344     	   bits specifying the starting page. */
345     	readb(shared_mem + start_page);
346     	mem_on(ioaddr, shared_mem, start_page);
347     
348     	memcpy_toio(shared_mem, buf, count);
349     	mem_off(ioaddr);
350     }
351     
352     static int
353     e21_close(struct net_device *dev)
354     {
355     	short ioaddr = dev->base_addr;
356     
357     	if (ei_debug > 1)
358     		printk("%s: Shutting down ethercard.\n", dev->name);
359     
360     	free_irq(dev->irq, dev);
361     	dev->irq = ei_status.saved_irq;
362     
363     	/* Shut off the interrupt line and secondary interface. */
364     	inb(ioaddr + E21_IRQ_LOW);
365     	outb(0, ioaddr + E21_ASIC);
366     	inb(ioaddr + E21_IRQ_HIGH); 			/* High IRQ bit, and if_port. */
367     	outb(0, ioaddr + E21_ASIC);
368     
369     	ei_close(dev);
370     
371     	/* Double-check that the memory has been turned off, because really
372     	   really bad things happen if it isn't. */
373     	mem_off(ioaddr);
374     
375     	return 0;
376     }
377     
378     
379     #ifdef MODULE
380     #define MAX_E21_CARDS	4	/* Max number of E21 cards per module */
381     static struct net_device dev_e21[MAX_E21_CARDS];
382     static int io[MAX_E21_CARDS];
383     static int irq[MAX_E21_CARDS];
384     static int mem[MAX_E21_CARDS];
385     static int xcvr[MAX_E21_CARDS];		/* choose int. or ext. xcvr */
386     
387     MODULE_PARM(io, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
388     MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
389     MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
390     MODULE_PARM(xcvr, "1-" __MODULE_STRING(MAX_E21_CARDS) "i");
391     MODULE_PARM_DESC(io, "E2100 I/O base address(es)");
392     MODULE_PARM_DESC(irq, "E2100 IRQ number(s)");
393     MODULE_PARM_DESC(mem, " E2100 memory base address(es)");
394     MODULE_PARM_DESC(xcvr, "E2100 tranceiver(s) (0=internal, 1=external)");
395     
396     /* This is set up so that only a single autoprobe takes place per call.
397     ISA device autoprobes on a running machine are not recommended. */
398     int
399     init_module(void)
400     {
401     	int this_dev, found = 0;
402     
403     	for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
404     		struct net_device *dev = &dev_e21[this_dev];
405     		dev->irq = irq[this_dev];
406     		dev->base_addr = io[this_dev];
407     		dev->mem_start = mem[this_dev];
408     		dev->mem_end = xcvr[this_dev];	/* low 4bits = xcvr sel. */
409     		dev->init = e2100_probe;
410     		if (io[this_dev] == 0)  {
411     			if (this_dev != 0) break; /* only autoprobe 1st one */
412     			printk(KERN_NOTICE "e2100.c: Presently autoprobing (not recommended) for a single card.\n");
413     		}
414     		if (register_netdev(dev) != 0) {
415     			printk(KERN_WARNING "e2100.c: No E2100 card found (i/o = 0x%x).\n", io[this_dev]);
416     			if (found != 0) {	/* Got at least one. */
417     				return 0;
418     			}
419     			return -ENXIO;
420     		}
421     		found++;
422     	}
423     	return 0;
424     }
425     
426     void
427     cleanup_module(void)
428     {
429     	int this_dev;
430     
431     	for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
432     		struct net_device *dev = &dev_e21[this_dev];
433     		if (dev->priv != NULL) {
434     			void *priv = dev->priv;
435     			/* NB: e21_close() handles free_irq */
436     			release_region(dev->base_addr, E21_IO_EXTENT);
437     			unregister_netdev(dev);
438     			kfree(priv);
439     		}
440     	}
441     }
442     #endif /* MODULE */
443     
444     /*
445      * Local variables:
446      *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c e2100.c"
447      *  version-control: t
448      *  tab-width: 4
449      *  kept-new-versions: 5
450      * End:
451      */
452