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