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