This source file includes following definitions.
- hp_plus_probe
- hpp_probe1
- hpp_open
- hpp_close
- hpp_reset_8390
- hpp_io_block_input
- hpp_mem_block_input
- hpp_io_block_output
- hpp_mem_block_output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 static char *version =
22 "hp-plus.c:v1.10 9/24/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
23
24 #include <linux/config.h>
25 #include <linux/string.h>
26 #include <linux/kernel.h>
27 #include <linux/sched.h>
28 #include <linux/errno.h>
29 #include <linux/ioport.h>
30 #include <asm/system.h>
31 #include <asm/io.h>
32
33 #ifdef start_bh_atomic
34 #include <linux/netdevice.h>
35 #include <linux/etherdevice.h>
36 #else
37 #include "dev.h"
38 #endif
39
40 #include "8390.h"
41 extern struct device *init_etherdev(struct device *dev, int sizeof_private,
42 unsigned long *mem_startp);
43
44
45 static unsigned int hpplus_portlist[] =
46 {0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0};
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 #define HP_ID 0x00
74 #define HP_PAGING 0x02
75 #define HPP_OPTION 0x04
76 #define HPP_OUT_ADDR 0x08
77 #define HPP_IN_ADDR 0x0A
78 #define HP_DATAPORT 0x0c
79 #define NIC_OFFSET 0x10
80 #define HP_IO_EXTENT 32
81
82 #define HP_START_PG 0x00
83 #define HP_STOP_PG 0x80
84
85
86 enum PageName {
87 Perf_Page = 0,
88 MAC_Page = 1,
89 HW_Page = 2,
90 LAN_Page = 4,
91 ID_Page = 6 };
92
93
94 enum HP_Option {
95 NICReset = 1, ChipReset = 2,
96 EnableIRQ = 4, FakeIntr = 8, BootROMEnb = 0x10, IOEnb = 0x20,
97 MemEnable = 0x40, ZeroWait = 0x80, MemDisable = 0x1000, };
98
99 int hpplus_probe(struct device *dev);
100 int hpp_probe1(struct device *dev, int ioaddr);
101
102 static void hpp_reset_8390(struct device *dev);
103 static int hpp_open(struct device *dev);
104 static int hpp_close(struct device *dev);
105 static int hpp_mem_block_input(struct device *dev, int count,
106 char *buf, int ring_offset);
107 static void hpp_mem_block_output(struct device *dev, int count,
108 const unsigned char *buf, const start_page);
109 static int hpp_io_block_input(struct device *dev, int count,
110 char *buf, int ring_offset);
111 static void hpp_io_block_output(struct device *dev, int count,
112 const unsigned char *buf, const start_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 char *name = "HP-PC-LAN+";
152 int mem_start;
153
154
155 if (inw(ioaddr + HP_ID) != 0x4850
156 || (inw(ioaddr + HP_PAGING) & 0xfff0) != 0x5300)
157 return ENODEV;
158
159 if (dev == NULL)
160 dev = init_etherdev(0, sizeof(struct ei_device), 0);
161
162 printk("%s: %s at %#3x,", dev->name, name, ioaddr);
163
164
165 outw(MAC_Page, ioaddr + HP_PAGING);
166
167 for(i = 0; i < ETHER_ADDR_LEN; i++) {
168 unsigned char inval = inb(ioaddr + 8 + i);
169 dev->dev_addr[i] = inval;
170 checksum += inval;
171 printk(" %2.2x", inval);
172 }
173 checksum += inb(ioaddr + 14);
174
175 if (checksum != 0xff) {
176 printk(" bad checksum %2.2x.\n", checksum);
177 return ENODEV;
178 } else {
179
180 outw(ID_Page, ioaddr + HP_PAGING);
181 printk(" ID %4.4x", inw(ioaddr + 12));
182 }
183
184
185 snarf_region(ioaddr, HP_IO_EXTENT);
186
187
188 outw(HW_Page, ioaddr + HP_PAGING);
189 {
190 int irq = inb(ioaddr + 13) & 0x0f;
191 int option = inw(ioaddr + HPP_OPTION);
192
193 dev->irq = irq;
194 if (option & MemEnable) {
195 mem_start = inw(ioaddr + 9) << 8;
196 printk(", IRQ %d, memory address %#x.\n", irq, mem_start);
197 } else {
198 mem_start = 0;
199 printk(", IRQ %d, programmed-I/O mode.\n", irq);
200 }
201 }
202
203 printk( "%s%s", KERN_INFO, version);
204
205
206 outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
207
208
209 dev->base_addr = ioaddr + NIC_OFFSET;
210
211 ethdev_init(dev);
212
213 dev->open = &hpp_open;
214 dev->stop = &hpp_close;
215
216 ei_status.name = name;
217 ei_status.word16 = 0;
218 ei_status.tx_start_page = HP_START_PG;
219 ei_status.rx_start_page = HP_START_PG + TX_2X_PAGES;
220 ei_status.stop_page = HP_STOP_PG;
221
222 ei_status.reset_8390 = &hpp_reset_8390;
223 ei_status.block_input = &hpp_io_block_input;
224 ei_status.block_output = &hpp_io_block_output;
225
226
227 if (mem_start) {
228 ei_status.block_input = &hpp_mem_block_input;
229 ei_status.block_output = &hpp_mem_block_output;
230 dev->mem_start = mem_start;
231 dev->rmem_start = dev->mem_start + TX_2X_PAGES*256;
232 dev->mem_end = dev->rmem_end
233 = dev->mem_start + (HP_STOP_PG - HP_START_PG)*256;
234 }
235
236 outw(Perf_Page, ioaddr + HP_PAGING);
237 NS8390_init(dev, 0);
238
239 outw(inw(ioaddr + HPP_OPTION) & ~EnableIRQ, ioaddr + HPP_OPTION);
240
241 return 0;
242 }
243
244 static int
245 hpp_open(struct device *dev)
246 {
247 int ioaddr = dev->base_addr - NIC_OFFSET;
248 int option_reg;
249
250 if (request_irq(dev->irq, &ei_interrupt, 0, "hp-plus")) {
251 return -EAGAIN;
252 }
253
254
255 option_reg = inw(ioaddr + HPP_OPTION);
256 outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
257 SLOW_DOWN_IO; SLOW_DOWN_IO;
258
259 outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
260
261
262 outw(HW_Page, ioaddr + HP_PAGING);
263 outw((HP_START_PG + TX_2X_PAGES) | ((HP_STOP_PG - 1) << 8), ioaddr + 14);
264
265
266 outw(Perf_Page, ioaddr + HP_PAGING);
267
268 return ei_open(dev);
269 }
270
271 static int
272 hpp_close(struct device *dev)
273 {
274 int ioaddr = dev->base_addr - NIC_OFFSET;
275 int option_reg = inw(ioaddr + HPP_OPTION);
276
277 free_irq(dev->irq);
278 irq2dev_map[dev->irq] = NULL;
279 NS8390_init(dev, 0);
280 outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset,
281 ioaddr + HPP_OPTION);
282
283 return 0;
284 }
285
286 static void
287 hpp_reset_8390(struct device *dev)
288 {
289 int ioaddr = dev->base_addr - NIC_OFFSET;
290 int option_reg = inw(ioaddr + HPP_OPTION);
291
292 if (ei_debug > 1) printk("resetting the 8390 time=%ld...", jiffies);
293
294 outw(option_reg & ~(NICReset + ChipReset), ioaddr + HPP_OPTION);
295
296 SLOW_DOWN_IO;
297 SLOW_DOWN_IO;
298 ei_status.txing = 0;
299 outw(option_reg | (EnableIRQ + NICReset + ChipReset), ioaddr + HPP_OPTION);
300
301 SLOW_DOWN_IO; SLOW_DOWN_IO;
302
303
304 if ((inb_p(ioaddr+NIC_OFFSET+EN0_ISR) & ENISR_RESET) == 0)
305 printk("%s: hp_reset_8390() did not complete.\n", dev->name);
306
307 if (ei_debug > 1) printk("8390 reset done (%ld).", jiffies);
308 return;
309 }
310
311
312
313
314 static int
315 hpp_io_block_input(struct device *dev, int count, char *buf, int ring_offset)
316 {
317 int ioaddr = dev->base_addr - NIC_OFFSET;
318
319 outw(ring_offset, ioaddr + HPP_IN_ADDR);
320 insw(ioaddr + HP_DATAPORT, buf, count>>1);
321 if (count & 0x01)
322 buf[count-1] = inw(ioaddr + HP_DATAPORT);
323 return ring_offset + count;
324 }
325
326 static int
327 hpp_mem_block_input(struct device *dev, int count, char *buf, int ring_offset)
328 {
329 int ioaddr = dev->base_addr - NIC_OFFSET;
330 int option_reg = inw(ioaddr + HPP_OPTION);
331
332 outw(ring_offset, ioaddr + HPP_IN_ADDR);
333
334 outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
335
336 memcpy(buf, (char*)dev->mem_start, (count + 3) & ~3);
337 outw(option_reg, ioaddr + HPP_OPTION);
338
339 return ring_offset + count;
340 }
341
342
343
344 static void
345 hpp_io_block_output(struct device *dev, int count,
346 const unsigned char *buf, const start_page)
347 {
348 int ioaddr = dev->base_addr - NIC_OFFSET;
349 outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
350 outsl(ioaddr + HP_DATAPORT, buf, (count+3)>>2);
351 return;
352 }
353
354 static void
355 hpp_mem_block_output(struct device *dev, int count,
356 const unsigned char *buf, const start_page)
357 {
358 int ioaddr = dev->base_addr - NIC_OFFSET;
359 int option_reg = inw(ioaddr + HPP_OPTION);
360
361 outw(start_page << 8, ioaddr + HPP_OUT_ADDR);
362 outw(option_reg & ~(MemDisable + BootROMEnb), ioaddr + HPP_OPTION);
363 memcpy((char *)dev->mem_start, buf, (count + 3) & ~3);
364 outw(option_reg, ioaddr + HPP_OPTION);
365
366 return;
367 }
368
369
370
371
372
373
374
375
376
377
378