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