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