This source file includes following definitions.
- el2_probe
- el2_pio_probe
- el2_probe1
- el2_open
- el2_close
- el2_reset_8390
- el2_init_card
- el2_block_output
- el2_block_input
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 static char *version =
26 "3c503.c:v1.10 9/23/93 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
27
28 #include <linux/config.h>
29 #include <linux/kernel.h>
30 #include <linux/sched.h>
31 #include <linux/errno.h>
32 #include <linux/string.h>
33 #include <linux/delay.h>
34 #include <asm/io.h>
35 #include <asm/system.h>
36
37 #include <linux/netdevice.h>
38
39 #include "8390.h"
40 #include "3c503.h"
41
42 extern struct device *init_etherdev(struct device *dev, int sizeof_private,
43 unsigned long *mem_startp);
44
45 int el2_probe(struct device *dev);
46 int el2_pio_probe(struct device *dev);
47 int el2_probe1(struct device *dev, int ioaddr);
48
49
50 static unsigned int netcard_portlist[] =
51 { 0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0};
52
53 #define EL2_IO_EXTENT 16
54
55 #ifdef HAVE_DEVLIST
56
57
58 struct netdev_entry el2_drv =
59 {"3c503", el2_probe, EL1_IO_EXTENT, 0};
60 struct netdev_entry el2pio_drv =
61 {"3c503pio", el2_pioprobe1, EL1_IO_EXTENT, netcard_portlist};
62 #endif
63
64 static int el2_open(struct device *dev);
65 static int el2_close(struct device *dev);
66 static void el2_reset_8390(struct device *dev);
67 static void el2_init_card(struct device *dev);
68 static void el2_block_output(struct device *dev, int count,
69 const unsigned char *buf, const start_page);
70 static int el2_block_input(struct device *dev, int count, char *buf,
71 int ring_offset);
72
73
74
75
76
77
78
79
80
81 int
82 el2_probe(struct device *dev)
83 {
84 int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0};
85 int base_addr = dev->base_addr;
86
87 if (base_addr > 0x1ff)
88 return el2_probe1(dev, base_addr);
89 else if (base_addr != 0)
90 return ENXIO;
91
92 for (addr = addrs; *addr; addr++) {
93 int i;
94 unsigned int base_bits = *(unsigned char *)*addr;
95
96 for(i = 7; i >= 0; i--, base_bits >>= 1)
97 if (base_bits & 0x1)
98 break;
99 if (base_bits != 1)
100 continue;
101 if (check_region(netcard_portlist[i], EL2_IO_EXTENT))
102 continue;
103 if (el2_probe1(dev, netcard_portlist[i]) == 0)
104 return 0;
105 }
106 #if ! defined(no_probe_nonshared_memory) && ! defined (HAVE_DEVLIST)
107 return el2_pio_probe(dev);
108 #else
109 return ENODEV;
110 #endif
111 }
112
113 #ifndef HAVE_DEVLIST
114
115
116 int
117 el2_pio_probe(struct device *dev)
118 {
119 int i;
120 int base_addr = dev ? dev->base_addr : 0;
121
122 if (base_addr > 0x1ff)
123 return el2_probe1(dev, base_addr);
124 else if (base_addr != 0)
125 return ENXIO;
126
127 for (i = 0; netcard_portlist[i]; i++) {
128 int ioaddr = netcard_portlist[i];
129 if (check_region(ioaddr, EL2_IO_EXTENT))
130 continue;
131 if (el2_probe1(dev, ioaddr) == 0)
132 return 0;
133 }
134
135 return ENODEV;
136 }
137 #endif
138
139
140
141
142 int
143 el2_probe1(struct device *dev, int ioaddr)
144 {
145 int i, iobase_reg, membase_reg, saved_406;
146 static unsigned version_printed = 0;
147
148
149 if (inb(ioaddr + 0x408) == 0xff) {
150 udelay(1000);
151 return ENODEV;
152 }
153
154
155
156 iobase_reg = inb(ioaddr+0x403);
157 membase_reg = inb(ioaddr+0x404);
158
159 if ( (iobase_reg & (iobase_reg - 1))
160 || (membase_reg & (membase_reg - 1))) {
161 return ENODEV;
162 }
163 saved_406 = inb_p(ioaddr + 0x406);
164 outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406);
165 outb_p(ECNTRL_THIN, ioaddr + 0x406);
166
167 outb(ECNTRL_SAPROM|ECNTRL_THIN, ioaddr + 0x406);
168 if ( inb(ioaddr + 0) != 0x02
169 || inb(ioaddr + 1) != 0x60
170 || inb(ioaddr + 2) != 0x8c) {
171
172 outb(saved_406, ioaddr + 0x406);
173 return ENODEV;
174 }
175
176 snarf_region(ioaddr, EL2_IO_EXTENT);
177
178 if (dev == NULL)
179 dev = init_etherdev(0, sizeof(struct ei_device), 0);
180
181 if (ei_debug && version_printed++ == 0)
182 printk(version);
183
184 dev->base_addr = ioaddr;
185 ethdev_init(dev);
186
187 printk("%s: 3c503 at %#3x,", dev->name, ioaddr);
188
189
190 for (i = 0; i < 6; i++)
191 printk(" %2.2x", dev->dev_addr[i] = inb(ioaddr + i));
192
193
194 outb(ECNTRL_THIN, ioaddr + 0x406);
195
196
197 if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg);
198 outb(EGACFR_NORM, ioaddr + 0x405);
199
200
201
202
203
204 #if defined(EI8390_THICK) || defined(EL2_AUI)
205 ei_status.interface_num = 1;
206 #else
207 ei_status.interface_num = dev->mem_end & 0xf;
208 #endif
209
210 if ((membase_reg & 0xf0) == 0) {
211 dev->mem_start = 0;
212 } else {
213 dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) +
214 ((membase_reg & 0xA0) ? 0x4000 : 0);
215
216 #define EL2_MEMSIZE (EL2SM_STOP_PG - EL2SM_START_PG)*256
217 #ifdef EL2MEMTEST
218
219 {
220 int *mem_base = (int *)dev->mem_start;
221 int memtest_value = 0xbbadf00d;
222 mem_base[0] = 0xba5eba5e;
223 for (i = 1; i < EL2_MEMSIZE/sizeof(mem_base[0]); i++) {
224 mem_base[i] = memtest_value;
225 if (mem_base[0] != 0xba5eba5e
226 || mem_base[i] != memtest_value) {
227 printk(" memory failure or memory address conflict.\n");
228 dev->mem_start = 0;
229 break;
230 }
231 memtest_value += 0x55555555;
232 mem_base[i] = 0;
233 }
234 }
235 #endif
236
237
238
239 dev->mem_end = dev->rmem_end = dev->mem_start + EL2_MEMSIZE;
240 dev->rmem_start = TX_PAGES*256 + dev->mem_start;
241 }
242
243
244 ei_status.name = "3C503";
245 ei_status.tx_start_page = EL2SM_START_PG;
246 ei_status.rx_start_page = EL2SM_START_PG + TX_PAGES;
247 ei_status.stop_page = EL2SM_STOP_PG;
248 ei_status.reset_8390 = &el2_reset_8390;
249 ei_status.block_input = &el2_block_input;
250 ei_status.block_output = &el2_block_output;
251
252 if (dev->irq == 2)
253 dev->irq = 9;
254 else if (dev->irq > 5 && dev->irq != 9) {
255 printk("\n3c503: configured interrupt %d invalid, using autoIRQ.\n",
256 dev->irq);
257 dev->irq = 0;
258 }
259
260 ei_status.saved_irq = dev->irq;
261
262 dev->start = 0;
263 dev->open = &el2_open;
264 dev->stop = &el2_close;
265
266 if (dev->mem_start)
267 printk("\n%s: %s with shared memory at %#6lx-%#6lx,\n",
268 dev->name, ei_status.name, dev->mem_start, dev->mem_end-1);
269 else
270 printk("\n%s: %s using programmed I/O (REJUMPER for SHARED MEMORY).\n",
271 dev->name, ei_status.name);
272
273 if (ei_debug > 1)
274 printk(version);
275
276 return 0;
277 }
278
279 static int
280 el2_open(struct device *dev)
281 {
282
283 if (dev->irq < 2) {
284 int irqlist[] = {5, 9, 3, 4, 0};
285 int *irqp = irqlist;
286
287 outb(EGACFR_NORM, E33G_GACFR);
288 do {
289 if (request_irq (*irqp, NULL, 0, "bogus") != -EBUSY) {
290
291 autoirq_setup(0);
292 outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
293 outb_p(0x00, E33G_IDCFR);
294 if (*irqp == autoirq_report(0)
295 && request_irq (dev->irq = *irqp, &ei_interrupt, 0, "3c503") == 0)
296 break;
297 }
298 } while (*++irqp);
299 if (*irqp == 0) {
300 outb(EGACFR_IRQOFF, E33G_GACFR);
301 return -EAGAIN;
302 }
303 } else {
304 if (request_irq(dev->irq, &ei_interrupt, 0, "3c503")) {
305 return -EAGAIN;
306 }
307 }
308 el2_init_card(dev);
309 return ei_open(dev);
310 }
311
312 static int
313 el2_close(struct device *dev)
314 {
315 free_irq(dev->irq);
316 dev->irq = ei_status.saved_irq;
317 irq2dev_map[dev->irq] = NULL;
318 outb(EGACFR_IRQOFF, E33G_GACFR);
319
320 NS8390_init(dev, 0);
321
322 return 0;
323 }
324
325
326
327
328
329 static void
330 el2_reset_8390(struct device *dev)
331 {
332 if (ei_debug > 1) {
333 printk("%s: Resetting the 3c503 board...", dev->name);
334 printk("%#x=%#02x %#x=%#02x %#x=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
335 E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
336 }
337 outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
338 ei_status.txing = 0;
339 outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
340 el2_init_card(dev);
341 if (ei_debug > 1) printk("done\n");
342 }
343
344
345 static void
346 el2_init_card(struct device *dev)
347 {
348
349 outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
350
351
352
353 outb(ei_status.rx_start_page, E33G_STARTPG);
354 outb(ei_status.stop_page, E33G_STOPPG);
355
356
357 outb(0xff, E33G_VP2);
358 outb(0xff, E33G_VP1);
359 outb(0x00, E33G_VP0);
360
361 outb_p(0x00, dev->base_addr + EN0_IMR);
362
363 outb(EGACFR_NORM, E33G_GACFR);
364
365
366 outb_p((0x04 << (dev->irq == 9 ? 2 : dev->irq)), E33G_IDCFR);
367 outb_p(8, E33G_DRQCNT);
368 outb_p(0x20, E33G_DMAAH);
369 outb_p(0x00, E33G_DMAAL);
370 return;
371 }
372
373
374
375 static void
376 el2_block_output(struct device *dev, int count,
377 const unsigned char *buf, const start_page)
378 {
379 int i;
380 int boguscount = 0;
381
382
383 outb(EGACFR_NORM, E33G_GACFR);
384
385 if (dev->mem_start) {
386 void *dest_addr = (void *)(dev->mem_start +
387 ((start_page - ei_status.tx_start_page) << 8));
388 memcpy(dest_addr, buf, count);
389 if (ei_debug > 2 && memcmp(dest_addr, buf, count))
390 printk("%s: 3c503 send_packet() bad memory copy @ %#5x.\n",
391 dev->name, (int) dest_addr);
392 return;
393 }
394
395
396 outb(0x00, E33G_DMAAL);
397 outb_p(start_page, E33G_DMAAH);
398 outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT
399 | ECNTRL_START, E33G_CNTRL);
400
401
402
403
404 for(i = 0; i < count; i++) {
405 if (i % 8 == 0)
406 while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
407 if (++boguscount > (i<<3) + 32) {
408 printk("%s: FIFO blocked in el2_block_output (at %d of %d, bc=%d).\n",
409 dev->name, i, count, boguscount);
410 return;
411 }
412 outb(buf[i], E33G_FIFOH);
413 }
414 outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
415 return;
416 }
417
418
419 static int
420 el2_block_input(struct device *dev, int count, char *buf, int ring_offset)
421 {
422 int boguscount = 0;
423 int end_of_ring = dev->rmem_end;
424 unsigned int i;
425
426
427 if (dev->mem_start) {
428 ring_offset -= (EL2SM_START_PG<<8);
429 if (dev->mem_start + ring_offset + count > end_of_ring) {
430
431 int semi_count = end_of_ring - (dev->mem_start + ring_offset);
432 memcpy(buf, (char *)dev->mem_start + ring_offset, semi_count);
433 count -= semi_count;
434 memcpy(buf + semi_count, (char *)dev->rmem_start, count);
435 return dev->rmem_start + count;
436 }
437 memcpy(buf, (char *)dev->mem_start + ring_offset, count);
438 return ring_offset + count;
439 }
440
441 outb(ring_offset & 0xff, E33G_DMAAL);
442 outb_p((ring_offset >> 8) & 0xff, E33G_DMAAH);
443 outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
444 | ECNTRL_START, E33G_CNTRL);
445
446
447
448 for(i = 0; i < count; i++) {
449 if (i % 8 == 0)
450 while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
451 if (++boguscount > (i<<3) + 32) {
452 printk("%s: FIFO blocked in el2_block_input() (at %d of %d, bc=%d).\n",
453 dev->name, i, count, boguscount);
454 boguscount = 0;
455 break;
456 }
457 buf[i] = inb_p(E33G_FIFOH);
458 }
459 outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
460 return 0;
461 }
462
463
464
465
466
467
468
469