This source file includes following definitions.
- mem_on
- mem_off
- e2100_probe
- e21_probe1
- e21_open
- e21_reset_8390
- e21_block_input
- e21_block_output
- e21_close
- init_module
- cleanup_module
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
26
27
28
29
30
31
32
33
34 static const char *version =
35 "e2100.c:v1.01 7/21/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
36
37 #ifdef MODULE
38 #include <linux/module.h>
39 #include <linux/version.h>
40 #endif
41
42 #include <linux/kernel.h>
43 #include <linux/sched.h>
44 #include <linux/errno.h>
45 #include <linux/string.h>
46 #include <asm/io.h>
47 #include <asm/system.h>
48 #include <linux/ioport.h>
49
50 #include <linux/netdevice.h>
51 #include "8390.h"
52
53 static int e21_probe_list[] = {0x300, 0x280, 0x380, 0x220, 0};
54
55
56
57
58 #define E21_NIC_OFFSET 0
59 #define E21_ASIC 0x10
60 #define E21_MEM_ENABLE 0x10
61 #define E21_MEM_ON 0x05
62 #define E21_MEM_ON_8 0x07
63 #define E21_MEM_BASE 0x11
64 #define E21_IRQ_LOW 0x12
65 #define E21_IRQ_HIGH 0x14
66 #define E21_MEDIA 0x14
67 #define E21_ALT_IFPORT 0x02
68 #define E21_BIG_MEM 0x04
69 #define E21_SAPROM 0x10
70 #define E21_IO_EXTENT 0x20
71
72 extern inline void mem_on(short port, volatile char *mem_base,
73 unsigned char start_page )
74 {
75
76
77 mem_base[start_page];
78 inb(port + E21_MEM_ENABLE);
79 outb(E21_MEM_ON, port + E21_MEM_ENABLE + E21_MEM_ON);
80 }
81
82 extern inline void mem_off(short port)
83 {
84 inb(port + E21_MEM_ENABLE);
85 outb(0x00, port + E21_MEM_ENABLE);
86 }
87
88
89
90
91
92 #define E21_RX_START_PG 0x00
93 #define E21_RX_STOP_PG 0x30
94 #define E21_BIG_RX_STOP_PG 0xF0
95 #define E21_TX_START_PG E21_RX_STOP_PG
96
97 int e2100_probe(struct device *dev);
98 int e21_probe1(struct device *dev, int ioaddr);
99
100 static int e21_open(struct device *dev);
101 static void e21_reset_8390(struct device *dev);
102 static int e21_block_input(struct device *dev, int count,
103 char *buf, int ring_offset);
104 static void e21_block_output(struct device *dev, int count,
105 const unsigned char *buf, const start_page);
106 static int e21_close(struct device *dev);
107
108
109
110
111
112
113
114
115
116 int e2100_probe(struct device *dev)
117 {
118 int *port;
119 int base_addr = dev->base_addr;
120
121 if (base_addr > 0x1ff)
122 return e21_probe1(dev, base_addr);
123 else if (base_addr != 0)
124 return ENXIO;
125
126 for (port = e21_probe_list; *port; port++) {
127 if (check_region(*port, E21_IO_EXTENT))
128 continue;
129 if (e21_probe1(dev, *port) == 0)
130 return 0;
131 }
132
133 return ENODEV;
134 }
135
136 int e21_probe1(struct device *dev, int ioaddr)
137 {
138 int i, status;
139 unsigned char *station_addr = dev->dev_addr;
140
141
142 if (inb(ioaddr + E21_SAPROM + 0) != 0x00
143 || inb(ioaddr + E21_SAPROM + 1) != 0x00
144 || inb(ioaddr + E21_SAPROM + 2) != 0x1d)
145 return ENODEV;
146
147
148 outb(E8390_NODMA + E8390_STOP, ioaddr);
149 SLOW_DOWN_IO;
150 status = inb(ioaddr);
151 if (status != 0x21 && status != 0x23)
152 return ENODEV;
153
154
155 for (i = 0; i < 6; i++)
156 station_addr[i] = inb(ioaddr + E21_SAPROM + i);
157
158 inb(ioaddr + E21_MEDIA);
159 outb(0, ioaddr + E21_ASIC);
160
161 printk("%s: E21** at %#3x,", dev->name, ioaddr);
162 for (i = 0; i < 6; i++)
163 printk(" %02X", station_addr[i]);
164
165 if (dev->irq < 2) {
166 int irqlist[] = {15,11,10,12,5,9,3,4}, i;
167 for (i = 0; i < 8; i++)
168 if (request_irq (irqlist[i], NULL, 0, "bogus") != -EBUSY) {
169 dev->irq = irqlist[i];
170 break;
171 }
172 if (i >= 8) {
173 printk(" unable to get IRQ %d.\n", dev->irq);
174 return EAGAIN;
175 }
176 } else if (dev->irq == 2)
177 dev->irq = 9;
178
179
180 request_region(ioaddr, E21_IO_EXTENT, "e2100");
181
182
183 dev->base_addr = ioaddr;
184
185 ethdev_init(dev);
186
187 ei_status.name = "E2100";
188 ei_status.word16 = 1;
189 ei_status.tx_start_page = E21_TX_START_PG;
190 ei_status.rx_start_page = E21_RX_START_PG;
191 ei_status.stop_page = E21_RX_STOP_PG;
192 ei_status.saved_irq = dev->irq;
193
194
195
196 if (dev->mem_end & 15)
197 dev->if_port = dev->mem_end & 7;
198 else {
199 dev->if_port = 0;
200 inb(ioaddr + E21_MEDIA);
201 for(i = 0; i < 6; i++)
202 if (station_addr[i] != inb(ioaddr + E21_SAPROM + 8 + i)) {
203 dev->if_port = 1;
204 break;
205 }
206 }
207
208
209
210
211 if (dev->mem_start == 0)
212 dev->mem_start = 0xd0000;
213
214 #ifdef notdef
215
216
217 dev->rmem_start = dev->mem_start + TX_PAGES*256;
218 dev->mem_end = dev->rmem_end = dev->mem_start + 2*1024;
219 #endif
220
221 printk(", IRQ %d, %s media, memory @ %#lx.\n", dev->irq,
222 dev->if_port ? "secondary" : "primary", dev->mem_start);
223
224 if (ei_debug > 0)
225 printk(version);
226
227 ei_status.reset_8390 = &e21_reset_8390;
228 ei_status.block_input = &e21_block_input;
229 ei_status.block_output = &e21_block_output;
230 dev->open = &e21_open;
231 dev->stop = &e21_close;
232 NS8390_init(dev, 0);
233
234 return 0;
235 }
236
237 static int
238 e21_open(struct device *dev)
239 {
240 short ioaddr = dev->base_addr;
241 int rc;
242
243 if (request_irq(dev->irq, ei_interrupt, 0, "e2100")) {
244 return EBUSY;
245 }
246 irq2dev_map[dev->irq] = dev;
247
248
249 inb(ioaddr + E21_IRQ_LOW);
250 outb(0, ioaddr + E21_ASIC + (dev->irq & 7));
251 inb(ioaddr + E21_IRQ_HIGH);
252 outb(0, ioaddr + E21_ASIC + (dev->irq > 7 ? 1:0)
253 + (dev->if_port ? E21_ALT_IFPORT : 0));
254 inb(ioaddr + E21_MEM_BASE);
255 outb(0, ioaddr + E21_ASIC + ((dev->mem_start >> 17) & 7));
256
257 rc = ei_open(dev);
258 if (rc != 0) return rc;
259 #ifdef MODULE
260 MOD_INC_USE_COUNT;
261 #endif
262 return 0;
263 }
264
265 static void
266 e21_reset_8390(struct device *dev)
267 {
268 short ioaddr = dev->base_addr;
269
270 outb(0x01, ioaddr);
271 if (ei_debug > 1) printk("resetting the E2180x3 t=%ld...", jiffies);
272 ei_status.txing = 0;
273
274
275
276 if (ei_debug > 1) printk("reset done\n");
277 return;
278 }
279
280
281
282
283 static int
284 e21_block_input(struct device *dev, int count, char *buf, int ring_offset)
285 {
286 short ioaddr = dev->base_addr;
287 char *shared_mem = (char *)dev->mem_start;
288 int start_page = (ring_offset>>8);
289
290 mem_on(ioaddr, shared_mem, start_page);
291
292
293 if (count == 4)
294 ((int*)buf)[0] = ((int*)shared_mem)[0];
295 else
296 memcpy(buf, shared_mem + (ring_offset & 0xff), count);
297
298
299 mem_off(ioaddr);
300
301 return 0;
302 }
303
304 static void
305 e21_block_output(struct device *dev, int count, const unsigned char *buf,
306 int start_page)
307 {
308 short ioaddr = dev->base_addr;
309 volatile char *shared_mem = (char *)dev->mem_start;
310
311
312
313 *(shared_mem + start_page);
314 mem_on(ioaddr, shared_mem, start_page);
315
316 memcpy((char*)shared_mem, buf, count);
317 mem_off(ioaddr);
318 }
319
320 static int
321 e21_close(struct device *dev)
322 {
323 short ioaddr = dev->base_addr;
324
325 if (ei_debug > 1)
326 printk("%s: Shutting down ethercard.\n", dev->name);
327
328 free_irq(dev->irq);
329 dev->irq = ei_status.saved_irq;
330
331
332 inb(ioaddr + E21_IRQ_LOW);
333 outb(0, ioaddr + E21_ASIC);
334 inb(ioaddr + E21_IRQ_HIGH);
335 outb(0, ioaddr + E21_ASIC);
336
337 irq2dev_map[dev->irq] = NULL;
338
339 NS8390_init(dev, 0);
340
341
342
343 mem_off(ioaddr);
344
345 #ifdef MODULE
346 MOD_DEC_USE_COUNT;
347 #endif
348
349 return 0;
350 }
351
352 #ifdef HAVE_DEVLIST
353 struct netdev_entry e21_drv =
354 {"e21", e21_probe1, E21_IO_EXTENT, e21_probe_list};
355 #endif
356
357 #ifdef MODULE
358 char kernel_version[] = UTS_RELEASE;
359 static char devicename[9] = { 0, };
360 static struct device dev_e2100 = {
361 devicename,
362 0, 0, 0, 0,
363 0, 0,
364 0, 0, 0, NULL, e2100_probe };
365
366 int io = 0x300;
367 int irq = 0;
368
369 int init_module(void)
370 {
371 if (io == 0)
372 printk("e2100: You should not use auto-probing with insmod!\n");
373 dev_e2100.base_addr = io;
374 dev_e2100.irq = irq;
375 if (register_netdev(&dev_e2100) != 0) {
376 printk("e2100: register_netdev() returned non-zero.\n");
377 return -EIO;
378 }
379 return 0;
380 }
381
382 void
383 cleanup_module(void)
384 {
385 if (MOD_IN_USE)
386 printk("e2100: device busy, remove delayed\n");
387 else
388 {
389 unregister_netdev(&dev_e2100);
390
391
392 release_region(dev_e2100.base_addr, E21_IO_EXTENT);
393 }
394 }
395 #endif
396
397
398
399
400
401
402
403
404