1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36static 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#include <linux/kernel.h>
41#include <linux/errno.h>
42#include <linux/string.h>
43#include <linux/ioport.h>
44#include <linux/netdevice.h>
45#include <linux/etherdevice.h>
46#include <linux/init.h>
47#include <linux/interrupt.h>
48#include <linux/delay.h>
49
50#include <asm/io.h>
51#include <asm/system.h>
52
53#include "8390.h"
54
55#define DRV_NAME "e2100"
56
57static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0};
58
59
60
61
62#define E21_NIC_OFFSET 0
63#define E21_ASIC 0x10
64#define E21_MEM_ENABLE 0x10
65#define E21_MEM_ON 0x05
66#define E21_MEM_ON_8 0x07
67#define E21_MEM_BASE 0x11
68#define E21_IRQ_LOW 0x12
69#define E21_IRQ_HIGH 0x14
70#define E21_MEDIA 0x14
71#define E21_ALT_IFPORT 0x02
72#define E21_BIG_MEM 0x04
73#define E21_SAPROM 0x10
74#define E21_IO_EXTENT 0x20
75
76static inline void mem_on(short port, volatile char __iomem *mem_base,
77 unsigned char start_page )
78{
79
80
81 readb(mem_base+start_page);
82 inb(port + E21_MEM_ENABLE);
83 outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON);
84}
85
86static inline void mem_off(short port)
87{
88 inb(port + E21_MEM_ENABLE);
89 outb(0x00, port + E21_MEM_ENABLE);
90}
91
92
93
94
95
96#define E21_RX_START_PG 0x00
97#define E21_RX_STOP_PG 0x30
98#define E21_BIG_RX_STOP_PG 0xF0
99#define E21_TX_START_PG E21_RX_STOP_PG
100
101static int e21_probe1(struct net_device *dev, int ioaddr);
102
103static int e21_open(struct net_device *dev);
104static void e21_reset_8390(struct net_device *dev);
105static void e21_block_input(struct net_device *dev, int count,
106 struct sk_buff *skb, int ring_offset);
107static void e21_block_output(struct net_device *dev, int count,
108 const unsigned char *buf, int start_page);
109static void e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
110 int ring_page);
111static int e21_open(struct net_device *dev);
112static int e21_close(struct net_device *dev);
113
114
115
116
117
118
119
120
121
122static int __init do_e2100_probe(struct net_device *dev)
123{
124 int *port;
125 int base_addr = dev->base_addr;
126 int irq = dev->irq;
127
128 if (base_addr > 0x1ff)
129 return e21_probe1(dev, base_addr);
130 else if (base_addr != 0)
131 return -ENXIO;
132
133 for (port = e21_probe_list; *port; port++) {
134 dev->irq = irq;
135 if (e21_probe1(dev, *port) == 0)
136 return 0;
137 }
138
139 return -ENODEV;
140}
141
142#ifndef MODULE
143struct net_device * __init e2100_probe(int unit)
144{
145 struct net_device *dev = alloc_ei_netdev();
146 int err;
147
148 if (!dev)
149 return ERR_PTR(-ENOMEM);
150
151 sprintf(dev->name, "eth%d", unit);
152 netdev_boot_setup_check(dev);
153
154 err = do_e2100_probe(dev);
155 if (err)
156 goto out;
157 return dev;
158out:
159 free_netdev(dev);
160 return ERR_PTR(err);
161}
162#endif
163
164static const struct net_device_ops e21_netdev_ops = {
165 .ndo_open = e21_open,
166 .ndo_stop = e21_close,
167
168 .ndo_start_xmit = ei_start_xmit,
169 .ndo_tx_timeout = ei_tx_timeout,
170 .ndo_get_stats = ei_get_stats,
171 .ndo_set_rx_mode = ei_set_multicast_list,
172 .ndo_validate_addr = eth_validate_addr,
173 .ndo_set_mac_address = eth_mac_addr,
174 .ndo_change_mtu = eth_change_mtu,
175#ifdef CONFIG_NET_POLL_CONTROLLER
176 .ndo_poll_controller = ei_poll,
177#endif
178};
179
180static int __init e21_probe1(struct net_device *dev, int ioaddr)
181{
182 int i, status, retval;
183 unsigned char *station_addr = dev->dev_addr;
184 static unsigned version_printed;
185
186 if (!request_region(ioaddr, E21_IO_EXTENT, DRV_NAME))
187 return -EBUSY;
188
189
190 if (inb(ioaddr + E21_SAPROM + 0) != 0x00 ||
191 inb(ioaddr + E21_SAPROM + 1) != 0x00 ||
192 inb(ioaddr + E21_SAPROM + 2) != 0x1d) {
193 retval = -ENODEV;
194 goto out;
195 }
196
197
198 outb(E8390_NODMA + E8390_STOP, ioaddr);
199 udelay(1);
200 status = inb(ioaddr);
201 if (status != 0x21 && status != 0x23) {
202 retval = -ENODEV;
203 goto out;
204 }
205
206
207 for (i = 0; i < 6; i++)
208 station_addr[i] = inb(ioaddr + E21_SAPROM + i);
209
210 inb(ioaddr + E21_MEDIA);
211 outb(0, ioaddr + E21_ASIC);
212
213 if (ei_debug && version_printed++ == 0)
214 printk(version);
215
216 for (i = 0; i < 6; i++)
217 printk(" %02X", station_addr[i]);
218
219 if (dev->irq < 2) {
220 static const int irqlist[] = {15, 11, 10, 12, 5, 9, 3, 4};
221 for (i = 0; i < ARRAY_SIZE(irqlist); i++)
222 if (request_irq (irqlist[i], NULL, 0, "bogus", NULL) != -EBUSY) {
223 dev->irq = irqlist[i];
224 break;
225 }
226 if (i >= ARRAY_SIZE(irqlist)) {
227 printk(" unable to get IRQ %d.\n", dev->irq);
228 retval = -EAGAIN;
229 goto out;
230 }
231 } else if (dev->irq == 2)
232 dev->irq = 9;
233
234
235 dev->base_addr = ioaddr;
236
237 ei_status.name = "E2100";
238 ei_status.word16 = 1;
239 ei_status.tx_start_page = E21_TX_START_PG;
240 ei_status.rx_start_page = E21_RX_START_PG;
241 ei_status.stop_page = E21_RX_STOP_PG;
242 ei_status.saved_irq = dev->irq;
243
244
245
246 if (dev->mem_end & 15)
247 dev->if_port = dev->mem_end & 7;
248 else {
249 dev->if_port = 0;
250 inb(ioaddr + E21_MEDIA);
251 for(i = 0; i < 6; i++)
252 if (station_addr[i] != inb(ioaddr + E21_SAPROM + 8 + i)) {
253 dev->if_port = 1;
254 break;
255 }
256 }
257
258
259
260
261 if (dev->mem_start == 0)
262 dev->mem_start = 0xd0000;
263
264 ei_status.mem = ioremap(dev->mem_start, 2*1024);
265 if (!ei_status.mem) {
266 printk("unable to remap memory\n");
267 retval = -EAGAIN;
268 goto out;
269 }
270
271#ifdef notdef
272
273
274 ei_status.rmem_start = dev->mem_start + TX_PAGES*256;
275 dev->mem_end = ei_status.rmem_end = dev->mem_start + 2*1024;
276#endif
277
278 printk(", IRQ %d, %s media, memory @ %#lx.\n", dev->irq,
279 dev->if_port ? "secondary" : "primary", dev->mem_start);
280
281 ei_status.reset_8390 = &e21_reset_8390;
282 ei_status.block_input = &e21_block_input;
283 ei_status.block_output = &e21_block_output;
284 ei_status.get_8390_hdr = &e21_get_8390_hdr;
285
286 dev->netdev_ops = &e21_netdev_ops;
287 NS8390_init(dev, 0);
288
289 retval = register_netdev(dev);
290 if (retval)
291 goto out;
292 return 0;
293out:
294 release_region(ioaddr, E21_IO_EXTENT);
295 return retval;
296}
297
298static int
299e21_open(struct net_device *dev)
300{
301 short ioaddr = dev->base_addr;
302 int retval;
303
304 if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev)))
305 return retval;
306
307
308 inb(ioaddr + E21_IRQ_LOW);
309 outb(0, ioaddr + E21_ASIC + (dev->irq & 7));
310 inb(ioaddr + E21_IRQ_HIGH);
311 outb(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0)
312 + (dev->if_port ? E21_ALT_IFPORT : 0));
313 inb(ioaddr + E21_MEM_BASE);
314 outb(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7));
315
316 ei_open(dev);
317 return 0;
318}
319
320static void
321e21_reset_8390(struct net_device *dev)
322{
323 short ioaddr = dev->base_addr;
324
325 outb(0x01, ioaddr);
326 if (ei_debug > 1) printk("resetting the E2180x3 t=%ld...", jiffies);
327 ei_status.txing = 0;
328
329
330
331 if (ei_debug > 1) printk("reset done\n");
332}
333
334
335
336
337static void
338e21_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
339{
340
341 short ioaddr = dev->base_addr;
342 char __iomem *shared_mem = ei_status.mem;
343
344 mem_on(ioaddr, shared_mem, ring_page);
345
346#ifdef notdef
347
348 memcpy_fromio(hdr, shared_mem, sizeof(struct e8390_pkt_hdr));
349#else
350 ((unsigned int*)hdr)[0] = readl(shared_mem);
351#endif
352
353
354 mem_off(ioaddr);
355
356}
357
358
359
360
361static void
362e21_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
363{
364 short ioaddr = dev->base_addr;
365 char __iomem *shared_mem = ei_status.mem;
366
367 mem_on(ioaddr, shared_mem, (ring_offset>>8));
368
369 memcpy_fromio(skb->data, ei_status.mem + (ring_offset & 0xff), count);
370
371 mem_off(ioaddr);
372}
373
374static void
375e21_block_output(struct net_device *dev, int count, const unsigned char *buf,
376 int start_page)
377{
378 short ioaddr = dev->base_addr;
379 volatile char __iomem *shared_mem = ei_status.mem;
380
381
382
383 readb(shared_mem + start_page);
384 mem_on(ioaddr, shared_mem, start_page);
385
386 memcpy_toio(shared_mem, buf, count);
387 mem_off(ioaddr);
388}
389
390static int
391e21_close(struct net_device *dev)
392{
393 short ioaddr = dev->base_addr;
394
395 if (ei_debug > 1)
396 printk("%s: Shutting down ethercard.\n", dev->name);
397
398 free_irq(dev->irq, dev);
399 dev->irq = ei_status.saved_irq;
400
401
402 inb(ioaddr + E21_IRQ_LOW);
403 outb(0, ioaddr + E21_ASIC);
404 inb(ioaddr + E21_IRQ_HIGH);
405 outb(0, ioaddr + E21_ASIC);
406
407 ei_close(dev);
408
409
410
411 mem_off(ioaddr);
412
413 return 0;
414}
415
416
417#ifdef MODULE
418#define MAX_E21_CARDS 4
419static struct net_device *dev_e21[MAX_E21_CARDS];
420static int io[MAX_E21_CARDS];
421static int irq[MAX_E21_CARDS];
422static int mem[MAX_E21_CARDS];
423static int xcvr[MAX_E21_CARDS];
424
425module_param_array(io, int, NULL, 0);
426module_param_array(irq, int, NULL, 0);
427module_param_array(mem, int, NULL, 0);
428module_param_array(xcvr, int, NULL, 0);
429MODULE_PARM_DESC(io, "I/O base address(es)");
430MODULE_PARM_DESC(irq, "IRQ number(s)");
431MODULE_PARM_DESC(mem, " memory base address(es)");
432MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)");
433MODULE_DESCRIPTION("Cabletron E2100 ISA ethernet driver");
434MODULE_LICENSE("GPL");
435
436
437
438
439int __init init_module(void)
440{
441 struct net_device *dev;
442 int this_dev, found = 0;
443
444 for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
445 if (io[this_dev] == 0) {
446 if (this_dev != 0) break;
447 printk(KERN_NOTICE "e2100.c: Presently autoprobing (not recommended) for a single card.\n");
448 }
449 dev = alloc_ei_netdev();
450 if (!dev)
451 break;
452 dev->irq = irq[this_dev];
453 dev->base_addr = io[this_dev];
454 dev->mem_start = mem[this_dev];
455 dev->mem_end = xcvr[this_dev];
456 if (do_e2100_probe(dev) == 0) {
457 dev_e21[found++] = dev;
458 continue;
459 }
460 free_netdev(dev);
461 printk(KERN_WARNING "e2100.c: No E2100 card found (i/o = 0x%x).\n", io[this_dev]);
462 break;
463 }
464 if (found)
465 return 0;
466 return -ENXIO;
467}
468
469static void cleanup_card(struct net_device *dev)
470{
471
472 iounmap(ei_status.mem);
473 release_region(dev->base_addr, E21_IO_EXTENT);
474}
475
476void __exit
477cleanup_module(void)
478{
479 int this_dev;
480
481 for (this_dev = 0; this_dev < MAX_E21_CARDS; this_dev++) {
482 struct net_device *dev = dev_e21[this_dev];
483 if (dev) {
484 unregister_netdev(dev);
485 cleanup_card(dev);
486 free_netdev(dev);
487 }
488 }
489}
490#endif
491