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