This source file includes following definitions.
- hp_plus_probe
- hpp_probe1
- hpp_open
- hpp_close
- hpp_reset_8390
- hpp_io_get_8390_hdr
- hpp_io_block_input
- hpp_mem_get_8390_hdr
- hpp_mem_block_input
- hpp_io_block_output
- hpp_mem_block_output
- 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 static const char *version =
22 "hp-plus.c:v1.10 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
23
24 #include <linux/module.h>
25
26 #include <linux/string.h>
27 #include <linux/kernel.h>
28 #include <linux/sched.h>
29 #include <linux/errno.h>
30 #include <linux/ioport.h>
31 #include <linux/netdevice.h>
32 #include <linux/etherdevice.h>
33
34 #include <asm/system.h>
35 #include <asm/io.h>
36
37
38 #include "8390.h"
39
40
41 static unsigned int hpplus_portlist[] =
42 {0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 #define HP_ID 0x00
70 #define HP_PAGING 0x02
71 #define HPP_OPTION 0x04
72 #define HPP_OUT_ADDR 0x08
73 #define HPP_IN_ADDR 0x0A
74 #define HP_DATAPORT 0x0c
75 #define NIC_OFFSET 0x10
76 #define HP_IO_EXTENT 32
77
78 #define HP_START_PG 0x00
79 #define HP_STOP_PG 0x80
80
81
82 enum PageName {
83 Perf_Page = 0,
84 MAC_Page = 1,
85 HW_Page = 2,
86 LAN_Page = 4,
87 ID_Page = 6 };
88
89
90 enum HP_Option {
91 NICReset = 1, ChipReset = 2,
92 EnableIRQ = 4, FakeIntr = 8, BootROMEnb = 0x10, IOEnb = 0x20,
93 MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, };
94
95 int hp_plus_probe(struct device *dev);
96 int hpp_probe1(struct device *dev, int ioaddr);
97
98 static void hpp_reset_8390(struct device *dev);
99 static int hpp_open(struct device *dev);
100 static int hpp_close(struct device *dev);
101 static void hpp_mem_block_input(struct device *dev, int count,
102 struct sk_buff *skb, int ring_offset);
103 static void hpp_mem_block_output(struct device *dev, int count,
104 const unsigned char *buf, const start_page);
105 static void hpp_mem_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
106 int ring_page);
107 static void hpp_io_block_input(struct device *dev, int count,
108 struct sk_buff *skb, int ring_offset);
109 static void hpp_io_block_output(struct device *dev, int count,
110 const unsigned char *buf, const start_page);
111 static void hpp_io_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
112 int ring_page);
113
114
115
116
117 #ifdef HAVE_DEVLIST
118
119
120 struct netdev_entry hpplus_drv =
121 {"hpplus", hpp_probe1, HP_IO_EXTENT, hpplus_portlist};
122 #else
123
124 int hp_plus_probe(struct device *dev)
125 {
126 int i;
127 int base_addr = dev ? dev->base_addr : 0;
128
129 if (base_addr > 0x1ff)
130 return hpp_probe1(dev, base_addr);
131 else if (base_addr != 0)
132 return ENXIO;
133
134 for (i = 0; hpplus_portlist[i]; i++) {
135 int ioaddr = hpplus_portlist[i];
136 if (check_region(ioaddr, HP_IO_EXTENT))
137 continue;
138 if (hpp_probe1(dev, ioaddr) == 0)
139 return 0;
140 }
141
142 return ENODEV;
143 }
144 #endif
145
146
147 int hpp_probe1(struct device *dev, int ioaddr)
148 {
149 int i;
150 unsigned char checksum = 0;
151 const char *name = "HP-PC-LAN+";
152 int mem_start;
153 static unsigned version_printed = 0;
154
155
156 if (inw(ioaddr + HP_ID) != 0x4850
157 || (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300)
158 return ENODEV;
159
160
161 if (dev == NULL) {
162 printk("hp-plus.c: Passed a NULL device.\n");
163 dev = init_etherdev(0, 0);
164 }
165
166 if (ei_debug && version_printed++ == 0)
167 printk(version);
168
169 printk("%s: %s at %#3x,", dev->name, name, ioaddr);
170
171
172 outw(MAC_Page, ioaddr + HP_PAGING);
173
174 for(i = 0; i < ETHER_ADDR_LEN; i++) {
175 unsigned char inval = inb(ioaddr + 8 + i);
176 dev->dev_addr[i] = inval;
177 checksum += inval;
178 printk(" %2.2x", inval);
179 }
180 checksum += inb(ioaddr + 14);
181
182 if (checksum != 0xff) {
183 printk(" bad checksum %2.2x.\n", checksum);
184 return ENODEV;
185 } else {
186
187 outw(ID_Page, ioaddr + HP_PAGING);
188 printk(" ID %4.4x", inw(ioaddr + 12));
189 }
190
191
192 if (ethdev_init(dev)) {
193 printk ("hp-plus.c: unable to allocate memory for dev->priv.\n");
194 return -ENOMEM;
195 }
196
197
198 request_region(ioaddr, HP_IO_EXTENT,"hp-plus");
199
200
201 outw(HW_Page, ioaddr + HP_PAGING);
202 {
203 int irq = inb(ioaddr + 13) & 0x0f;
204 int option = inw(ioaddr + HPP_OPTION);
205
206 dev->irq = irq;
207 if (option & MemEnable) {
208 mem_start = inw(ioaddr + 9) << 8;
209 printk(", IRQ %d, memory address %#x.\n", irq, mem_start);
210 } else {
211 mem_start = 0;
212 printk(", IRQ %d, programmed-I/O mode.\n", irq);
213 }
214 }
215
216
217 outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
218
219
220 dev->base_addr = ioaddr + NIC_OFFSET;
221
222 dev->open = &hpp_open;
223 dev->stop = &hpp_close;
224
225 ei_status.name = name;
226 ei_status.word16 = 0;
227 ei_status.tx_start_page = HP_START_PG;
228 ei_status.rx_start_page = HP_START_PG + TX_2X_PAGES;
229 ei_status.stop_page = HP_STOP_PG;
230
231 ei_status.reset_8390 = &hpp_reset_8390;
232 ei_status.block_input = &hpp_io_block_input;
233 ei_status.block_output = &hpp_io_block_output;
234 ei_status.get_8390_hdr = &hpp_io_get_8390_hdr;
235
236
237 if (mem_start) {
238 ei_status.block_input = &hpp_mem_block_input;
239 ei_status.block_output = &hpp_mem_block_output;
240 ei_status.get_8390_hdr = &hpp_mem_get_8390_hdr;
241 dev->mem_start = mem_start;
242 dev->rmem_start = dev->mem_start + TX_2X_PAGES*256;
243 dev->mem_end = dev->rmem_end
244 = dev->mem_start + (HP_STOP_PG - HP_START_PG)*256;
245 }
246
247 outw(Perf_Page, ioaddr + HP_PAGING);
248 NS8390_init(dev, 0);
249
250 outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION);
251
252 return 0;
253 }
254
255 static int
256 hpp_open(struct device *dev)
257 {
258 int ioaddr = dev->base_addr - NIC_OFFSET;
259 int option_reg;
260
261 if (request_irq(dev->irq, &ei_interrupt, 0, "hp-plus", NULL)) {
262 return -EAGAIN;
263 }
264
265
266 option_reg = inw(ioaddr + HPP_OPTION);
267 outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
268 SLOW_DOWN_IO; SLOW_DOWN_IO;
269
270 outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
271
272
273 outw(HW_Page, ioaddr + HP_PAGING);
274 outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
275
276
277 outw(Perf_Page, ioaddr + HP_PAGING);
278
279 ei_open(dev);
280 MOD_INC_USE_COUNT;
281 return 0;
282 }
283
284 static int
285 hpp_close(struct device *dev)
286 {
287 int ioaddr = dev->base_addr - NIC_OFFSET;
288 int option_reg = inw(ioaddr + HPP_OPTION);
289
290 free_irq(dev->irq, NULL);
291 irq2dev_map[dev->irq] = NULL;
292 ei_close(dev);
293 outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset,
294 ioaddr + HPP_OPTION);
295
296 MOD_DEC_USE_COUNT;
297 return 0;
298 }
299
300 static void
301 hpp_reset_8390(struct device *dev)
302 {
303 int ioaddr = dev->base_addr - NIC_OFFSET;
304 int option_reg = inw(ioaddr + HPP_OPTION);
305
306 if (ei_debug > 1) printk("resetting the 8390 time=%ld...", jiffies);
307
308 outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
309
310 SLOW_DOWN_IO;
311 SLOW_DOWN_IO;
312 ei_status.txing = 0;
313 outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
314
315 SLOW_DOWN_IO; SLOW_DOWN_IO;
316
317
318 if ((inb_p(ioaddr+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
319 printk("%s: hp_reset_8390() did not complete.\n", dev->name);
320
321 if (ei_debug > 1) printk("8390 reset done (%ld).", jiffies);
322 return;
323 }
324
325
326
327
328 static void
329 hpp_io_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
330 {
331 int ioaddr = dev->base_addr - NIC_OFFSET;
332
333 outw((ring_page<<8), ioaddr + HPP_IN_ADDR);
334 insw(ioaddr + HP_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
335 }
336
337
338
339 static void
340 hpp_io_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
341 {
342 int ioaddr = dev->base_addr - NIC_OFFSET;
343 char *buf = skb->data;
344
345 outw(ring_offset, ioaddr + HPP_IN_ADDR);
346 insw(ioaddr + HP_DATAPORT, buf, count>>1);
347 if (count & 0x01)
348 buf[count-1] = inw(ioaddr + HP_DATAPORT);
349 }
350
351
352
353 static void
354 hpp_mem_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
355 {
356 int ioaddr = dev->base_addr - NIC_OFFSET;
357 int option_reg = inw(ioaddr + HPP_OPTION);
358
359 outw((ring_page<<8), ioaddr + HPP_IN_ADDR);
360 outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
361 memcpy_fromio(hdr, dev->mem_start, sizeof(struct e8390_pkt_hdr));
362 outw(option_reg, ioaddr + HPP_OPTION);
363 hdr->count = (hdr->count + 3) & ~3;
364 }
365
366 static void
367 hpp_mem_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
368 {
369 int ioaddr = dev->base_addr - NIC_OFFSET;
370 int option_reg = inw(ioaddr + HPP_OPTION);
371
372 outw(ring_offset, ioaddr + HPP_IN_ADDR);
373
374 outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
375
376
377
378
379
380 memcpy_fromio(skb->data, dev->mem_start, count);
381 outw(option_reg, ioaddr + HPP_OPTION);
382 }
383
384
385
386 static void
387 hpp_io_block_output(struct device *dev, int count,
388 const unsigned char *buf, const start_page)
389 {
390 int ioaddr = dev->base_addr - NIC_OFFSET;
391 outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
392 outsl(ioaddr + HP_DATAPORT, buf, (count+3)>>2);
393 return;
394 }
395
396 static void
397 hpp_mem_block_output(struct device *dev, int count,
398 const unsigned char *buf, const start_page)
399 {
400 int ioaddr = dev->base_addr - NIC_OFFSET;
401 int option_reg = inw(ioaddr + HPP_OPTION);
402
403 outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
404 outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
405 memcpy_toio(dev->mem_start, buf, (count + 3) & ~3);
406 outw(option_reg, ioaddr + HPP_OPTION);
407
408 return;
409 }
410
411
412 #ifdef MODULE
413 #define MAX_HPP_CARDS 4
414 #define NAMELEN 8
415 static char namelist[NAMELEN * MAX_HPP_CARDS] = { 0, };
416 static struct device dev_hpp[MAX_HPP_CARDS] = {
417 {
418 NULL,
419 0, 0, 0, 0,
420 0, 0,
421 0, 0, 0, NULL, NULL
422 },
423 };
424
425 static int io[MAX_HPP_CARDS] = { 0, };
426 static int irq[MAX_HPP_CARDS] = { 0, };
427
428
429
430 int
431 init_module(void)
432 {
433 int this_dev, found = 0;
434
435 for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
436 struct device *dev = &dev_hpp[this_dev];
437 dev->name = namelist+(NAMELEN*this_dev);
438 dev->irq = irq[this_dev];
439 dev->base_addr = io[this_dev];
440 dev->init = hp_plus_probe;
441 if (io[this_dev] == 0) {
442 if (this_dev != 0) break;
443 printk(KERN_NOTICE "hp-plus.c: Presently autoprobing (not recommended) for a single card.\n");
444 }
445 if (register_netdev(dev) != 0) {
446 printk(KERN_WARNING "hp-plus.c: No HP-Plus card found (i/o = 0x%x).\n", io[this_dev]);
447 if (found != 0) return 0;
448 return -ENXIO;
449 }
450 found++;
451 }
452
453 return 0;
454 }
455
456 void
457 cleanup_module(void)
458 {
459 int this_dev;
460
461 for (this_dev = 0; this_dev < MAX_HPP_CARDS; this_dev++) {
462 struct device *dev = &dev_hpp[this_dev];
463 if (dev->priv != NULL) {
464
465 int ioaddr = dev->base_addr - NIC_OFFSET;
466 kfree(dev->priv);
467 dev->priv = NULL;
468 release_region(ioaddr, HP_IO_EXTENT);
469 unregister_netdev(dev);
470 }
471 }
472 }
473 #endif
474
475
476
477
478
479
480
481
482
483