This source file includes following definitions.
- neprobe
- neprobe1
- ne_reset_8390
- ne_block_input
- ne_block_output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 static char *version =
19 "ne.c:v0.99-10 5/28/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 <asm/io.h>
25 #include <asm/system.h>
26
27 #include "dev.h"
28 #include "8390.h"
29
30
31 #define port_read(port,buf,nr) \
32 __asm__("cld;rep;insw": :"d" (port),"D" (buf),"c" (nr):"cx","di")
33 #define port_write(port,buf,nr) \
34 __asm__("cld;rep;outsw": :"d" (port),"S" (buf),"c" (nr):"cx","si")
35
36 #define port_read_b(port,buf,nr) \
37 __asm__("cld;rep;insb": :"d" (port),"D" (buf),"c" (nr):"cx","di")
38 #define port_write_b(port,buf,nr) \
39 __asm__("cld;rep;outsb": :"d" (port),"S" (buf),"c" (nr):"cx","si")
40
41 #define EN_CMD (dev->base_addr)
42 #define NE_BASE (dev->base_addr)
43 #define NE_DATAPORT 0x10
44 #define NE_RESET 0x1f
45
46 #define NE1SM_START_PG 0x20
47 #define NE1SM_STOP_PG 0x40
48 #define NESM_START_PG 0x40
49 #define NESM_STOP_PG 0x80
50
51 extern void NS8390_init(struct device *dev, int startp);
52 extern int ei_debug;
53 extern struct sigaction ei_sigaction;
54
55 int neprobe(int ioaddr, struct device *dev);
56 static int neprobe1(int ioaddr, struct device *dev, int verbose);
57
58 static void ne_reset_8390(struct device *dev);
59 static int ne_block_input(struct device *dev, int count,
60 char *buf, int ring_offset);
61 static void ne_block_output(struct device *dev, const int count,
62 const unsigned char *buf, const int start_page);
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 int neprobe(int ioaddr, struct device *dev)
87 {
88 int *port, ports[] = {0x300, 0x280, 0x320, 0x340, 0x360, 0};
89
90 if (ioaddr > 0x100)
91 return neprobe1(ioaddr, dev, 1);
92
93 for (port = &ports[0]; *port; port++)
94 if (inb_p(*port) != 0xff && neprobe1(*port, dev, 0))
95 return dev->base_addr = *port;
96 return 0;
97 }
98
99 static int neprobe1(int ioaddr, struct device *dev, int verbose)
100 {
101 int i;
102 unsigned char SA_prom[32];
103 int wordlength = 2;
104 int neX000, ctron, dlink;
105
106
107 if ( inb_p(ioaddr) == 0xFF) {
108 if (verbose) printk("8390 ethercard probe at %#3x failed.\n", ioaddr);
109 return 0;
110 }
111
112 printk("8390 ethercard probe at %#3x:", ioaddr);
113
114
115
116
117
118
119 {
120 struct {char value, offset; } program_seq[] = {
121 {E8390_NODMA+E8390_PAGE0+E8390_STOP, EN_CMD},
122 {0x48, EN0_DCFG},
123 {0x00, EN0_RCNTLO},
124 {0x00, EN0_RCNTHI},
125 {0x00, EN0_IMR},
126 {0xFF, EN0_ISR},
127 {E8390_RXOFF, EN0_RXCR},
128 {E8390_TXOFF, EN0_TXCR},
129 {32, EN0_RCNTLO},
130 {0x00, EN0_RCNTHI},
131 {0x00, EN0_RSARLO},
132 {0x00, EN0_RSARHI},
133 {E8390_RREAD+E8390_START, EN_CMD},
134 };
135 for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
136 outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
137 }
138 for(i = 0; i < 32 ; i+=2) {
139 SA_prom[i] = inb_p(ioaddr + NE_DATAPORT);
140 SA_prom[i+1] = inb_p(ioaddr + NE_DATAPORT);
141 if (SA_prom[i] != SA_prom[i+1])
142 wordlength = 1;
143 }
144
145 if (wordlength == 2) {
146
147 int tmp;
148 outb_p(0x49, ioaddr + EN0_DCFG);
149 tmp = inb_p(NE_BASE + NE_RESET);
150 ei_status.word16 = 1;
151 outb(tmp, NE_BASE + NE_RESET);
152
153 for (i = 0; i < 16; i++)
154 SA_prom[i] = SA_prom[i+i];
155 } else
156 ei_status.word16 = 0;
157
158 #if defined(show_all_SAPROM)
159
160 for(i = 0; i < sizeof(SA_prom); i++)
161 printk(" %2.2x", SA_prom[i]);
162 #else
163 for(i = 0; i < ETHER_ADDR_LEN; i++) {
164 dev->dev_addr[i] = SA_prom[i];
165 printk(" %2.2x", SA_prom[i]);
166 }
167 #endif
168
169 neX000 = (SA_prom[14] == 0x57 && SA_prom[15] == 0x57);
170 ctron = (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
171 dlink = (SA_prom[0] == 0x00 && SA_prom[1] == 0xDE && SA_prom[2] == 0x01);
172
173
174 if (neX000 && wordlength == 2) {
175 ei_status.name = "NE2000";
176 ei_status.tx_start_page = NESM_START_PG;
177 ei_status.stop_page = NESM_STOP_PG;
178 } else if (neX000 || dlink) {
179 ei_status.name = neX000 ? "NE1000" : "D-Link";
180 ei_status.tx_start_page = NE1SM_START_PG;
181 ei_status.stop_page = NE1SM_STOP_PG;
182 } else if (ctron) {
183 ei_status.name = "Cabletron";
184 ei_status.tx_start_page = 0x01;
185 ei_status.stop_page = (wordlength == 2) ? 0x40 : 0x20;
186 } else {
187 printk(" not found.\n");
188 return 0;
189 }
190 ei_status.rx_start_page = ei_status.tx_start_page + TX_PAGES;
191 #ifdef PACKETBUF_MEMSIZE
192
193 ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
194 #endif
195 dev->base_addr = ioaddr;
196
197 if (dev->irq < 2) {
198 int nic_base = dev->base_addr;
199 autoirq_setup(0);
200 outb_p(0x50, nic_base + EN0_IMR);
201 outb_p(0x00, nic_base + EN0_RCNTLO);
202 outb_p(0x00, nic_base + EN0_RCNTHI);
203 outb_p(E8390_RREAD+E8390_START, nic_base);
204 outb_p(0x00, nic_base + EN0_IMR);
205 dev->irq = autoirq_report(0);
206 if (ei_debug > 2)
207 printk(" autoirq is %d", dev->irq);
208 } else if (dev->irq == 2)
209
210
211 dev->irq = 9;
212
213
214
215 { int irqval = irqaction (dev->irq, &ei_sigaction);
216 if (irqval) {
217 printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval);
218 return 0;
219 }
220 }
221
222 printk("\n%s: %s found, using IRQ %d.\n",
223 dev->name, ei_status.name, dev->irq);
224 if (ei_debug > 1)
225 printk(version);
226 ei_status.reset_8390 = &ne_reset_8390;
227 ei_status.block_input = &ne_block_input;
228 ei_status.block_output = &ne_block_output;
229 NS8390_init(dev, 0);
230 return dev->base_addr;
231 }
232
233
234
235 static void
236 ne_reset_8390(struct device *dev)
237 {
238 int tmp = inb_p(NE_BASE + NE_RESET);
239 int reset_start_time = jiffies;
240
241 if (ei_debug > 1) printk("resetting the 8390 t=%d...", jiffies);
242 ei_status.txing = 0;
243
244 outb_p(tmp, NE_BASE + NE_RESET);
245
246 while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
247 if (jiffies - reset_start_time > 2) {
248 printk("%s: ne_reset_8390() did not complete.\n", dev->name);
249 break;
250 }
251 }
252
253
254
255
256
257
258 static int
259 ne_block_input(struct device *dev, int count, char *buf, int ring_offset)
260 {
261 int xfer_count = count;
262 int nic_base = dev->base_addr;
263
264 if (ei_status.dmaing) {
265 if (ei_debug > 0)
266 printk("%s: DMAing conflict in ne_block_input."
267 "[DMAstat:%1x][irqlock:%1x]\n",
268 dev->name, ei_status.dmaing, ei_status.irqlock);
269 return 0;
270 }
271 ei_status.dmaing |= 0x01;
272 outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, EN_CMD);
273 outb_p(count & 0xff, nic_base + EN0_RCNTLO);
274 outb_p(count >> 8, nic_base + EN0_RCNTHI);
275 outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
276 outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
277 outb_p(E8390_RREAD+E8390_START, EN_CMD);
278 if (ei_status.word16) {
279 port_read(NE_BASE + NE_DATAPORT,buf,count>>1);
280 if (count & 0x01)
281 buf[count-1] = inb(NE_BASE + NE_DATAPORT), xfer_count++;
282 } else {
283 port_read_b(NE_BASE + NE_DATAPORT, buf, count);
284 }
285
286
287
288 if (ei_debug > 0) {
289 int addr, tries = 20;
290 do {
291
292
293 int high = inb_p(nic_base + EN0_RSARHI);
294 int low = inb_p(nic_base + EN0_RSARLO);
295 addr = (high << 8) + low;
296 if (((ring_offset + xfer_count) & 0xff) == low)
297 break;
298 } while (--tries > 0);
299 if (tries <= 0)
300 printk("%s: RX transfer address mismatch,"
301 "%#4.4x (should be) vs. %#4.4x (actual).\n",
302 dev->name, ring_offset + xfer_count, addr);
303 }
304 ei_status.dmaing &= ~0x01;
305 return ring_offset + count;
306 }
307
308 static void
309 ne_block_output(struct device *dev, int count,
310 const unsigned char *buf, const int start_page)
311 {
312 int retries = 0;
313 int nic_base = NE_BASE;
314
315
316
317
318 if (ei_status.word16 && (count & 0x01))
319 count++;
320 if (ei_status.dmaing) {
321 if (ei_debug > 0)
322 printk("%s: DMAing conflict in ne_block_output."
323 "[DMAstat:%1x][irqlock:%1x]\n",
324 dev->name, ei_status.dmaing, ei_status.irqlock);
325 return;
326 }
327 ei_status.dmaing |= 0x02;
328
329 outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, EN_CMD);
330
331 retry:
332 #if defined(rw_bugfix)
333
334
335
336
337 outb_p(0x42, nic_base + EN0_RCNTLO);
338 outb_p(0x00, nic_base + EN0_RCNTHI);
339 outb_p(0x42, nic_base + EN0_RSARLO);
340 outb_p(0x00, nic_base + EN0_RSARHI);
341 outb_p(E8390_RREAD+E8390_START, EN_CMD);
342
343 SLOW_DOWN_IO;
344 SLOW_DOWN_IO;
345 SLOW_DOWN_IO;
346 #endif
347
348
349 outb_p(count & 0xff, nic_base + EN0_RCNTLO);
350 outb_p(count >> 8, nic_base + EN0_RCNTHI);
351 outb_p(0x00, nic_base + EN0_RSARLO);
352 outb_p(start_page, nic_base + EN0_RSARHI);
353
354 outb_p(E8390_RWRITE+E8390_START, EN_CMD);
355 if (ei_status.word16) {
356 port_write(NE_BASE + NE_DATAPORT, buf, count>>1);
357 } else {
358 port_write_b(NE_BASE + NE_DATAPORT, buf, count);
359 }
360
361
362
363 if (ei_debug > 0) {
364 int addr, tries = 20;
365 do {
366
367
368 int high = inb_p(nic_base + EN0_RSARHI);
369 int low = inb_p(nic_base + EN0_RSARLO);
370 addr = (high << 8) + low;
371 if ((start_page << 8) + count == addr)
372 break;
373 } while (--tries > 0);
374 if (tries <= 0) {
375 printk("%s: Packet buffer transfer address mismatch on TX,"
376 "%#4.4x vs. %#4.4x.\n",
377 dev->name, (start_page << 8) + count, addr);
378 if (retries++ == 0)
379 goto retry;
380 }
381 }
382 ei_status.dmaing &= ~0x02;
383 return;
384 }
385
386
387
388
389
390
391
392
393