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
34static const char *version =
35 "lne390.c: Driver revision v0.99.1, 01/09/2000\n";
36
37#include <linux/module.h>
38#include <linux/eisa.h>
39#include <linux/kernel.h>
40#include <linux/errno.h>
41#include <linux/string.h>
42#include <linux/delay.h>
43#include <linux/init.h>
44#include <linux/netdevice.h>
45#include <linux/etherdevice.h>
46
47#include <asm/io.h>
48#include <asm/system.h>
49
50#include "8390.h"
51
52#define DRV_NAME "lne390"
53
54static int lne390_probe1(struct net_device *dev, int ioaddr);
55
56static void lne390_reset_8390(struct net_device *dev);
57
58static void lne390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page);
59static void lne390_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset);
60static void lne390_block_output(struct net_device *dev, int count, const unsigned char *buf, const int start_page);
61
62#define LNE390_START_PG 0x00
63#define LNE390_STOP_PG 0x80
64
65#define LNE390_ID_PORT 0xc80
66#define LNE390_IO_EXTENT 0x20
67#define LNE390_SA_PROM 0x16
68#define LNE390_RESET_PORT 0xc84
69#define LNE390_NIC_OFFSET 0x00
70
71#define LNE390_ADDR0 0x00
72#define LNE390_ADDR1 0x80
73#define LNE390_ADDR2 0xe5
74
75#define LNE390_ID0 0x10009835
76#define LNE390_ID1 0x11009835
77
78#define LNE390_CFG1 0xc84
79#define LNE390_CFG2 0xc90
80
81
82
83
84
85
86
87#define LNE390_D_PROBE 0x01
88#define LNE390_D_RX_PKT 0x02
89#define LNE390_D_TX_PKT 0x04
90#define LNE390_D_IRQ 0x08
91
92#define LNE390_DEBUG 0
93
94static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
95static unsigned int shmem_mapA[] __initdata = {0xff, 0xfe, 0xfd, 0xfff, 0xffe, 0xffc, 0x0d, 0x0};
96static unsigned int shmem_mapB[] __initdata = {0xff, 0xfe, 0x0e, 0xfff, 0xffe, 0xffc, 0x0d, 0x0};
97
98
99
100
101
102
103
104static int __init do_lne390_probe(struct net_device *dev)
105{
106 unsigned short ioaddr = dev->base_addr;
107 int irq = dev->irq;
108 int mem_start = dev->mem_start;
109 int ret;
110
111 if (ioaddr > 0x1ff) {
112 if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME))
113 return -EBUSY;
114 ret = lne390_probe1(dev, ioaddr);
115 if (ret)
116 release_region(ioaddr, LNE390_IO_EXTENT);
117 return ret;
118 }
119 else if (ioaddr > 0)
120 return -ENXIO;
121
122 if (!EISA_bus) {
123#if LNE390_DEBUG & LNE390_D_PROBE
124 printk("lne390-debug: Not an EISA bus. Not probing high ports.\n");
125#endif
126 return -ENXIO;
127 }
128
129
130 for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
131 if (!request_region(ioaddr, LNE390_IO_EXTENT, DRV_NAME))
132 continue;
133 if (lne390_probe1(dev, ioaddr) == 0)
134 return 0;
135 release_region(ioaddr, LNE390_IO_EXTENT);
136 dev->irq = irq;
137 dev->mem_start = mem_start;
138 }
139
140 return -ENODEV;
141}
142
143#ifndef MODULE
144struct net_device * __init lne390_probe(int unit)
145{
146 struct net_device *dev = alloc_ei_netdev();
147 int err;
148
149 if (!dev)
150 return ERR_PTR(-ENOMEM);
151
152 sprintf(dev->name, "eth%d", unit);
153 netdev_boot_setup_check(dev);
154
155 err = do_lne390_probe(dev);
156 if (err)
157 goto out;
158 return dev;
159out:
160 free_netdev(dev);
161 return ERR_PTR(err);
162}
163#endif
164
165static int __init lne390_probe1(struct net_device *dev, int ioaddr)
166{
167 int i, revision, ret;
168 unsigned long eisa_id;
169
170 if (inb_p(ioaddr + LNE390_ID_PORT) == 0xff) return -ENODEV;
171
172#if LNE390_DEBUG & LNE390_D_PROBE
173 printk("lne390-debug: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + LNE390_ID_PORT));
174 printk("lne390-debug: config regs: %#x %#x\n",
175 inb(ioaddr + LNE390_CFG1), inb(ioaddr + LNE390_CFG2));
176#endif
177
178
179
180 eisa_id = inl(ioaddr + LNE390_ID_PORT);
181 if ((eisa_id != LNE390_ID0) && (eisa_id != LNE390_ID1)) {
182 return -ENODEV;
183 }
184
185 revision = (eisa_id >> 24) & 0x01;
186
187#if 0
188
189 if (inb(ioaddr + LNE390_SA_PROM + 0) != LNE390_ADDR0
190 || inb(ioaddr + LNE390_SA_PROM + 1) != LNE390_ADDR1
191 || inb(ioaddr + LNE390_SA_PROM + 2) != LNE390_ADDR2 ) {
192 printk("lne390.c: card not found");
193 for(i = 0; i < ETHER_ADDR_LEN; i++)
194 printk(" %02x", inb(ioaddr + LNE390_SA_PROM + i));
195 printk(" (invalid prefix).\n");
196 return -ENODEV;
197 }
198#endif
199
200 for(i = 0; i < ETHER_ADDR_LEN; i++)
201 dev->dev_addr[i] = inb(ioaddr + LNE390_SA_PROM + i);
202 printk("lne390.c: LNE390%X in EISA slot %d, address %pM.\n",
203 0xa+revision, ioaddr/0x1000, dev->dev_addr);
204
205 printk("lne390.c: ");
206
207
208 if (dev->irq == 0) {
209 unsigned char irq_reg = inb(ioaddr + LNE390_CFG2) >> 3;
210 dev->irq = irq_map[irq_reg & 0x07];
211 printk("using");
212 } else {
213
214 if (dev->irq == 2) dev->irq = 9;
215 printk("assigning");
216 }
217 printk(" IRQ %d,", dev->irq);
218
219 if ((ret = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev))) {
220 printk (" unable to get IRQ %d.\n", dev->irq);
221 return ret;
222 }
223
224 if (dev->mem_start == 0) {
225 unsigned char mem_reg = inb(ioaddr + LNE390_CFG2) & 0x07;
226
227 if (revision)
228 dev->mem_start = shmem_mapB[mem_reg] * 0x10000;
229 else
230 dev->mem_start = shmem_mapA[mem_reg] * 0x10000;
231 printk(" using ");
232 } else {
233
234 dev->mem_start &= 0xfff0000;
235 printk(" assigning ");
236 }
237
238 printk("%dkB memory at physical address %#lx\n",
239 LNE390_STOP_PG/4, dev->mem_start);
240
241
242
243
244
245
246
247 ei_status.mem = ioremap(dev->mem_start, LNE390_STOP_PG*0x100);
248 if (!ei_status.mem) {
249 printk(KERN_ERR "lne390.c: Unable to remap card memory above 1MB !!\n");
250 printk(KERN_ERR "lne390.c: Try using EISA SCU to set memory below 1MB.\n");
251 printk(KERN_ERR "lne390.c: Driver NOT installed.\n");
252 ret = -EAGAIN;
253 goto cleanup;
254 }
255 printk("lne390.c: remapped %dkB card memory to virtual address %p\n",
256 LNE390_STOP_PG/4, ei_status.mem);
257
258 dev->mem_start = (unsigned long)ei_status.mem;
259 dev->mem_end = dev->mem_start + (LNE390_STOP_PG - LNE390_START_PG)*256;
260
261
262 dev->base_addr = ioaddr;
263
264 ei_status.name = "LNE390";
265 ei_status.tx_start_page = LNE390_START_PG;
266 ei_status.rx_start_page = LNE390_START_PG + TX_PAGES;
267 ei_status.stop_page = LNE390_STOP_PG;
268 ei_status.word16 = 1;
269
270 if (ei_debug > 0)
271 printk(version);
272
273 ei_status.reset_8390 = &lne390_reset_8390;
274 ei_status.block_input = &lne390_block_input;
275 ei_status.block_output = &lne390_block_output;
276 ei_status.get_8390_hdr = &lne390_get_8390_hdr;
277
278 dev->netdev_ops = &ei_netdev_ops;
279 NS8390_init(dev, 0);
280
281 ret = register_netdev(dev);
282 if (ret)
283 goto unmap;
284 return 0;
285unmap:
286 if (ei_status.reg0)
287 iounmap(ei_status.mem);
288cleanup:
289 free_irq(dev->irq, dev);
290 return ret;
291}
292
293
294
295
296
297
298static void lne390_reset_8390(struct net_device *dev)
299{
300 unsigned short ioaddr = dev->base_addr;
301
302 outb(0x04, ioaddr + LNE390_RESET_PORT);
303 if (ei_debug > 1) printk("%s: resetting the LNE390...", dev->name);
304
305 mdelay(2);
306
307 ei_status.txing = 0;
308 outb(0x01, ioaddr + LNE390_RESET_PORT);
309 if (ei_debug > 1) printk("reset done\n");
310
311 return;
312}
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329static void
330lne390_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
331{
332 void __iomem *hdr_start = ei_status.mem + ((ring_page - LNE390_START_PG)<<8);
333 memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
334 hdr->count = (hdr->count + 3) & ~3;
335}
336
337
338
339
340
341
342
343static void lne390_block_input(struct net_device *dev, int count, struct sk_buff *skb,
344 int ring_offset)
345{
346 void __iomem *xfer_start = ei_status.mem + ring_offset - (LNE390_START_PG<<8);
347
348 if (ring_offset + count > (LNE390_STOP_PG<<8)) {
349
350 int semi_count = (LNE390_STOP_PG<<8) - ring_offset;
351 memcpy_fromio(skb->data, xfer_start, semi_count);
352 count -= semi_count;
353 memcpy_fromio(skb->data + semi_count,
354 ei_status.mem + (TX_PAGES<<8), count);
355 } else {
356
357 memcpy_fromio(skb->data, xfer_start, count);
358 }
359}
360
361static void lne390_block_output(struct net_device *dev, int count,
362 const unsigned char *buf, int start_page)
363{
364 void __iomem *shmem = ei_status.mem + ((start_page - LNE390_START_PG)<<8);
365
366 count = (count + 3) & ~3;
367 memcpy_toio(shmem, buf, count);
368}
369
370
371#ifdef MODULE
372#define MAX_LNE_CARDS 4
373static struct net_device *dev_lne[MAX_LNE_CARDS];
374static int io[MAX_LNE_CARDS];
375static int irq[MAX_LNE_CARDS];
376static int mem[MAX_LNE_CARDS];
377
378module_param_array(io, int, NULL, 0);
379module_param_array(irq, int, NULL, 0);
380module_param_array(mem, int, NULL, 0);
381MODULE_PARM_DESC(io, "I/O base address(es)");
382MODULE_PARM_DESC(irq, "IRQ number(s)");
383MODULE_PARM_DESC(mem, "memory base address(es)");
384MODULE_DESCRIPTION("Mylex LNE390A/B EISA Ethernet driver");
385MODULE_LICENSE("GPL");
386
387int __init init_module(void)
388{
389 struct net_device *dev;
390 int this_dev, found = 0;
391
392 for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) {
393 if (io[this_dev] == 0 && this_dev != 0)
394 break;
395 dev = alloc_ei_netdev();
396 if (!dev)
397 break;
398 dev->irq = irq[this_dev];
399 dev->base_addr = io[this_dev];
400 dev->mem_start = mem[this_dev];
401 if (do_lne390_probe(dev) == 0) {
402 dev_lne[found++] = dev;
403 continue;
404 }
405 free_netdev(dev);
406 printk(KERN_WARNING "lne390.c: No LNE390 card found (i/o = 0x%x).\n", io[this_dev]);
407 break;
408 }
409 if (found)
410 return 0;
411 return -ENXIO;
412}
413
414static void cleanup_card(struct net_device *dev)
415{
416 free_irq(dev->irq, dev);
417 release_region(dev->base_addr, LNE390_IO_EXTENT);
418 iounmap(ei_status.mem);
419}
420
421void __exit cleanup_module(void)
422{
423 int this_dev;
424
425 for (this_dev = 0; this_dev < MAX_LNE_CARDS; this_dev++) {
426 struct net_device *dev = dev_lne[this_dev];
427 if (dev) {
428 unregister_netdev(dev);
429 cleanup_card(dev);
430 free_netdev(dev);
431 }
432 }
433}
434#endif
435
436